rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
authorGood Guy <good1.2guy@gmail.com>
Thu, 14 Apr 2016 22:47:20 +0000 (16:47 -0600)
committerGood Guy <good1.2guy@gmail.com>
Thu, 14 Apr 2016 22:47:20 +0000 (16:47 -0600)
20 files changed:
cinelerra-5.1/cinelerra/keyframepopup.C
cinelerra-5.1/cinelerra/keyframepopup.h
cinelerra-5.1/cinelerra/keyframepopup.inc
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/mwindowgui.h
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/guicast/bcdisplay.C
cinelerra-5.1/guicast/bcmenu.C
cinelerra-5.1/guicast/bcmenu.h
cinelerra-5.1/guicast/bcmenuitem.C
cinelerra-5.1/guicast/bcmenupopup.C
cinelerra-5.1/guicast/bcmenupopup.h
cinelerra-5.1/guicast/bcpopupmenu.C
cinelerra-5.1/guicast/bcpopupmenu.h
cinelerra-5.1/guicast/bctextbox.C
cinelerra-5.1/guicast/bctextbox.h
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/guicast/bcwindowbase.h
cinelerra-5.1/plugins/lens/lens.C
cinelerra-5.1/po/de.po

index d8528ae2c43370dbed48ed8370c0e0fb49cd5da4..45fdb127590a576257423ef85dc8551b99ae320b 100644 (file)
  * 
  */
 
+#include "apatchgui.h"
+#include "autoconf.h"
+#include "autos.h"
+#include "bcwindowbase.h"
+#include "cpanel.h"
+#include "cwindowgui.h" 
 #include "cwindow.h"
 #include "edl.h"
+#include "edlsession.h"
+#include "filexml.h"
+#include "gwindow.h"
+#include "gwindowgui.h"
 #include "keyframe.h"
 #include "keyframepopup.h"
 #include "language.h"
+#include "localsession.h"
+#include "maincursor.h"
+#include "mainmenu.h"
 #include "mainundo.h"
-#include "mwindow.h"
 #include "mwindowgui.h"
-#include "localsession.h"
-#include "cwindowgui.h" 
-#include "cpanel.h"
+#include "mwindow.h"
 #include "patchbay.h"
 #include "patchgui.h" 
-#include "apatchgui.h"
-#include "vpatchgui.h"
 #include "track.h"
-#include "maincursor.h"
-#include "bcwindowbase.h"
-#include "filexml.h"
-#include "edlsession.h"
-#include "autos.h"
+#include "vpatchgui.h"
 
 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
  : BC_PopupMenu(0, 0, 0, "", 0)
@@ -481,4 +485,84 @@ int KeyframePopupEdit::handle_event()
 }
 
 
+KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
+ : BC_PopupMenu(0, 0, 0, "", 0)
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+       this->keyframe_autos = 0;
+}
+
+KeyframeHidePopup::~KeyframeHidePopup()
+{
+}
+
+void KeyframeHidePopup::create_objects()
+{
+        add_item(new KeyframePopupHide(mwindow, this));
+}
+
+int KeyframeHidePopup::update(Autos *autos)
+{
+       this->keyframe_autos = autos;
+       return 0;
+}
+
+KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframeHidePopup *popup)
+ : BC_MenuItem(_("Hide keyframe type"))
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+}
+
+int KeyframePopupHide::handle_event()
+{
+// Get the array index of the curve
+       int update_gui = 0;
+       if(popup->keyframe_autos)
+       {
+               if(popup->keyframe_autos->type == Autos::AUTOMATION_TYPE_PLUGIN)
+               {
+                       mwindow->edl->session->auto_conf->plugins = 0;
+                       update_gui = 1;
+               }
+               else
+               {
+                       Track *track = popup->keyframe_autos->track;
+                       if(track)
+                       {
+                               Automation *automation = track->automation;
+                               if(automation)
+                               {
+                                       for(int i = 0; i < AUTOMATION_TOTAL; i++)
+                                       {
+                                               if(automation->autos[i] == popup->keyframe_autos)
+                                               {
+                                                       mwindow->edl->session->auto_conf->autos[i] = 0;
+                                                       update_gui = 1;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(update_gui)
+       {
+               mwindow->gui->update(0,
+                       1,      // 1 for incremental drawing.  2 for full refresh
+                       0,
+                       0,
+                       0,
+               0,   
+               0);
+               mwindow->gui->mainmenu->update_toggles(1);
+               mwindow->gui->unlock_window();
+               mwindow->gwindow->gui->update_toggles(1);
+               mwindow->gui->lock_window("KeyframePopupHide::handle_event");
+       }
+
+       return 1;
+}
 
index c512d0e025c8b0f5130c7083dcc80380e4d4245c..21df4abdc8365878c4a3b23323ff458674595590 100644 (file)
 #include "plugin.inc"
 #include "plugindialog.inc"
 #include "keyframe.inc"
+#include "keyframepopup.inc"
 #include "automation.h" 
 #include "floatauto.h"
 
 
-class KeyframePopupDelete;
-class KeyframePopupShow;
-class KeyframePopupCopy;
-class KeyframePopupCurveMode;
-class KeyframePopupEdit;
  
 class KeyframePopup : public BC_PopupMenu
 {
@@ -135,4 +130,28 @@ public:
        KeyframePopup *popup;
 };
 
+class KeyframeHidePopup : public BC_PopupMenu
+{
+public:
+        KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui);
+        ~KeyframeHidePopup();
+
+        void create_objects();
+       int update(Autos *autos);
+
+       MWindow *mwindow;
+       MWindowGUI *gui;
+       Autos *keyframe_autos;
+};
+
+class KeyframePopupHide : public BC_MenuItem
+{
+public:
+       KeyframePopupHide(MWindow *mwindow, KeyframeHidePopup *popup);
+       int handle_event();
+
+       MWindow *mwindow;
+       KeyframeHidePopup *popup;
+};
+
 #endif
index b316613a0db8556fe678a7e8b481aeced02a8161..3728f0c349162e2651e71aef8fbbdcd7138a739b 100644 (file)
 #ifndef KEYFRAMEPOPUP_INC
 #define KEYFRAMEPOPUP_INC
 
-
-
-
-
 class KeyframePopup;
-
-
-
-
-
+class KeyframePopupDelete;
+class KeyframePopupShow;
+class KeyframePopupCopy;
+class KeyframePopupCurveMode;
+class KeyframePopupEdit;
+class KeyframePopupHide;
+class KeyframeHidePopup;
 #endif
index 418146626e87d3da17cc405497531c9ab821fb09..43b3a1c76346e9e8737c97d5c669577cc5bd4930 100644 (file)
@@ -119,6 +119,7 @@ MWindowGUI::MWindowGUI(MWindow *mwindow)
        edit_menu = 0;
        plugin_menu = 0;
        keyframe_menu = 0;
+       keyframe_hide = 0;
        transition_menu = 0;
        remote_control = 0;
        cwindow_remote_handler = 0;
@@ -344,6 +345,8 @@ void MWindowGUI::create_objects()
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
        add_subwindow(keyframe_menu = new KeyframePopup(mwindow, this));
        keyframe_menu->create_objects();
+       add_subwindow(keyframe_hide = new KeyframeHidePopup(mwindow, this));
+       keyframe_hide->create_objects();
 
 
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
index 4d742667f042fac6ec01ed677d3513c15353f83a..f3c1dfea9f0a116e5b8c91ab370279fc0ca61f40 100644 (file)
@@ -191,6 +191,7 @@ public:
        EditPopup *edit_menu;
        PluginPopup *plugin_menu;
        KeyframePopup *keyframe_menu;
+       KeyframeHidePopup *keyframe_hide;
        TransitionPopup *transition_menu;
 
        MainClock *mainclock;
index 016e6aa3b5bff84e127f45e25d46d7443f1bc1fc..6d0fee37cbd5d08f7668cf48904d560dc8e2fed8 100644 (file)
@@ -2031,6 +2031,12 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                                        gui->keyframe_menu->activate_menu();
                                                        rerender = 1; // the position changes
                                                }
+                                               else if( autos )
+                                               {
+                                                       gui->keyframe_hide->update(autos);
+                                                       gui->keyframe_hide->activate_menu();
+                                                       rerender = 1; // the position changes
+                                               }
                                                if(buttonpress == 1 && ctrl_down() &&
                                                   AUTOMATION_TYPE_FLOAT == autos->get_type())
                                                        rerender = 1; // special case: curve mode changed
@@ -2506,7 +2512,7 @@ void TrackCanvas::draw_floatline(int center_pixel,
 
 // Not using slope intercept
        x1 = MAX(0, x1);
-       int prev_y = y1;
+       int prev_y = y1 + center_pixel;
 
 
 // Call by reference fails for some reason here
@@ -2529,6 +2535,7 @@ void TrackCanvas::draw_floatline(int center_pixel,
 // (int)(center_pixel - yscale / 2),
 // (int)(center_pixel + yscale / 2 - 1));
 
+//printf("draw_line(%d,%d,  %d,%d)\n", x - 1, prev_y  , x, y);
                        draw_line(x - 1, prev_y  , x, y   );
                }
                prev_y = y;
@@ -2853,10 +2860,10 @@ int TrackCanvas::do_float_autos(Track *track, Autos *autos, int cursor_x, int cu
                 autos->first ? autos->first : autos->default_auto;
 
        double ax = 0, ay = 0, ax2 = 0, ay2 = 0;
-       if( first_auto )
+       if( first_auto ) {
                calculate_auto_position(&ax, &ay, 0, 0, 0, 0,
                        first_auto, unit_start, zoom_units, yscale, autogrouptype);
-
+       }
        if( current )
                current = NEXT;
        else {
index 4525857f53a30b59a9bf88acc9e0fe8759eae67c..4bf17887a998ad61d4f4fac55006cdb32a578dfd 100644 (file)
@@ -344,7 +344,7 @@ int BC_Display::unset_all_repeaters(BC_WindowBase *window)
 
 void BC_Display::arm_repeat(int64_t duration)
 {
-       XEvent *event = new XEvent;
+       XEvent *event = BC_WindowBase::new_xevent();
        XClientMessageEvent *ptr = (XClientMessageEvent*)event;
        event->xany.window = 0;
        ptr->type = ClientMessage;
@@ -358,7 +358,7 @@ void BC_Display::arm_repeat(int64_t duration)
 
 void BC_Display::arm_completion(BC_WindowBase *window)
 {
-       XEvent *event = new XEvent;
+       XEvent *event = BC_WindowBase::new_xevent();
        XClientMessageEvent *ptr = (XClientMessageEvent*)event;
        event->xany.window = window->win;
        event->type = ClientMessage;
index 4745a445c49c3287a62c8da455c7319c693277e3..0deeec924b0d283f4a7d9a53d00a30f36ce55bb0 100644 (file)
@@ -70,9 +70,9 @@ int BC_Menu::add_item(BC_MenuItem* menuitem)
        return 0;
 }
 
-int BC_Menu::remove_item(BC_MenuItem *item)
+int BC_Menu::del_item(BC_MenuItem *item)
 {
-       menu_popup->remove_item(item, 0);
+       menu_popup->del_item(item);
        return 0;
 }
 
index 788f68983b380532510c5ab9095ecebd84db588f..a6b7e87c5f314c71381bacf1dc3df1f84fc4f02e 100644 (file)
@@ -50,7 +50,7 @@ public:
 // Called by user to add items
        int add_item(BC_MenuItem* menuitem);
 // Remove the item ptr and the object
-       int remove_item(BC_MenuItem* item = 0);
+       int del_item(BC_MenuItem* item=0);
        int total_menuitems();
        int set_text(char *text);
 
index 66f869532b4ba1f8a7673659e2f698f2a278d49c..6279bc6f0f4727b63fc4633bc21be3e0e4e4cf27 100644 (file)
@@ -68,8 +68,8 @@ BC_MenuItem::~BC_MenuItem()
        hotkey_text = 0;
        if(submenu) delete submenu;
        submenu = 0;
-// deletes this
-       if(menu_popup) menu_popup->remove_item(this, 1);
+       if(menu_popup)
+               menu_popup->remove_item(this);
 }
 
 void BC_MenuItem::reset()
index 0d418cb8c4f442b3657d55eea63fb4a87cb42b38..9ffa152ff513881a5f6b1abc79042e11cc239eee 100644 (file)
@@ -112,7 +112,12 @@ int BC_MenuPopup::add_item(BC_MenuItem *item)
        return 0;
 }
 
-int BC_MenuPopup::remove_item(BC_MenuItem *item, int recursive)
+int BC_MenuPopup::remove_item(BC_MenuItem *item)
+{
+       menu_items.remove(item);
+}
+
+int BC_MenuPopup::del_item(BC_MenuItem *item)
 {
        if(!item && menu_items.size() > 0)
        {
@@ -121,9 +126,9 @@ int BC_MenuPopup::remove_item(BC_MenuItem *item, int recursive)
 
        if(item)
        {
-               menu_items.remove(item);
+               remove_item(item);
                item->menu_popup = 0;
-               if(!recursive) delete item;
+               delete item;
        }
        return 0;
 }
index a70a50f72a8556b77969fcba9ef313fc046b8a08..fdc8d0b0fb3d4e296e9df5e356fa5bb663c0e4c7 100644 (file)
@@ -51,7 +51,8 @@ public:
                BC_MenuItem *menu_item, 
                BC_PopupMenu *popup_menu);
        int add_item(BC_MenuItem *item);
-       int remove_item(BC_MenuItem* item /* = 0 */, int recursive);
+       int del_item(BC_MenuItem* item);
+       int remove_item(BC_MenuItem* item);
        int total_menuitems();
 
 // Deactivates all submenus in a downward progression except for the exclude
index cefaea7f48e22be0e9667cb4f376d84e794d5509..d0bf3b3ae0dc7fff778051ac7890167b7becc72c 100644 (file)
@@ -208,7 +208,13 @@ int BC_PopupMenu::add_item(BC_MenuItem *item)
 
 int BC_PopupMenu::remove_item(BC_MenuItem *item)
 {
-       menu_popup->remove_item(item, 0);
+       menu_popup->remove_item(item);
+       return 0;
+}
+
+int BC_PopupMenu::del_item(BC_MenuItem *item)
+{
+       menu_popup->del_item(item);
        return 0;
 }
 
index f5de6d41880fc00b3ddbe2674396c93b29170918..88af58957b29115c5ef13a10b6f620021509e137 100644 (file)
@@ -59,6 +59,7 @@ public:
        char* get_text();
        int initialize();
        int add_item(BC_MenuItem *item);
+       int del_item(BC_MenuItem *item);
        int remove_item(BC_MenuItem *item);
        int total_items();
        BC_MenuItem* get_item(int i);
index 7a06046cff6c634ee988908d87ac032e8e5736f3..0bcf9f464440069c1b517eac99987d0064a6fd61 100644 (file)
@@ -475,7 +475,7 @@ void BC_TextBox::set_suggestions(ArrayList<char*> *suggestions, int column)
        }
 }
 
-void BC_TextBox::set_selection(int char1, int char2, int ibeam)
+void BC_TextBox::wset_selection(int char1, int char2, int ibeam)
 {
        highlight_letter1 = char1;
        highlight_letter2 = char2;
@@ -483,6 +483,29 @@ void BC_TextBox::set_selection(int char1, int char2, int ibeam)
        draw(1);
 }
 
+// count utf8 chars in text which occur before cp
+int BC_TextBox::wcpos(const char *text, const char *cp)
+{
+       int len = 0;
+       const unsigned char *bp = (const unsigned char *)text;
+       const unsigned char *ep = (const unsigned char *)cp;
+       while( bp < ep && *bp != 0 ) {
+               ++len;
+               int ch = *bp++;
+               if( ch < 0x80 ) continue;
+               int i = ch - 0x0c0;
+               int n = i<0? 0 : i<32? 1 : i<48? 2 : i<56? 3 : i<60? 4 : 5;
+               for( i=n; bp < ep && --i>=0 && (*bp&0xc0) == 0x80; ++bp );
+       }
+       return len;
+}
+
+void BC_TextBox::set_selection(int char1, int char2, int ibeam)
+{
+       const char *cp = get_text();
+       wset_selection(wcpos(cp, cp+char1), wcpos(cp, cp+char2), wcpos(cp, cp+ibeam));
+}
+
 int BC_TextBox::update(const char *text)
 {
 //printf("BC_TextBox::update 1 %d %s %s\n", tstrcmp(text), text, this->text);
@@ -2256,12 +2279,6 @@ int BC_TextBoxSuggestions::handle_event()
 }
 
 
-
-
-
-
-
-
 BC_ScrollTextBox::BC_ScrollTextBox(BC_WindowBase *parent_window,
        int x, int y, int w, int rows,
        const char *default_text, int default_size)
@@ -2412,6 +2429,11 @@ void BC_ScrollTextBox::set_selection(int char1, int char2, int ibeam)
        this->text->set_selection(char1, char2, ibeam);
 }
 
+void BC_ScrollTextBox::wset_selection(int char1, int char2, int ibeam)
+{
+       this->text->wset_selection(char1, char2, ibeam);
+}
+
 
 
 
index 3d1106e6e48f38bde571df2c6b04a4f205b06ddd..8ad635bc517c03d7cd7733c479bdcf681b43d615 100644 (file)
@@ -68,6 +68,7 @@ public:
 // Whenever the position of the text changes
        virtual int motion_event() { return 0; };
        void set_selection(int char1, int char2, int ibeam);
+       void wset_selection(int char1, int char2, int ibeam);
        int update(const char *text);
        int update(const wchar_t *wtext);
        int update(int64_t value);
@@ -98,6 +99,7 @@ public:
 // Set top left of text view
        void set_text_row(int row);
        int get_text_row();
+
        int reposition_window(int x, int y, int w = -1, int rows = -1);
        int uses_text();
 #ifdef X_HAVE_UTF8_STRING
@@ -106,6 +108,8 @@ public:
        static int calculate_h(BC_WindowBase *gui, int font, int has_border, int rows);
        static int calculate_row_h(int rows, BC_WindowBase *parent_window, int has_border = 1, int font = MEDIUMFONT);
        static int pixels_to_rows(BC_WindowBase *window, int font, int pixels);
+       static int wcpos(const char *text, const char *ep);
+
        void set_precision(int precision);
 // Whether to draw every time there is a keypress or rely on user to
 // follow up every keypress with an update().
@@ -242,6 +246,7 @@ public:
        void update(const char *text);
        void update(const wchar_t *wtext);
        void set_selection(int char1, int char2, int ibeam);
+       void wset_selection(int char1, int char2, int ibeam);
        void reposition_window(int x, int y, int w, int rows);
        int get_x();
        int get_y();
index 67226174a93a34ddf2f8514ad3f0ffba04b5fc90..8322837d3302ef1f39378a45bc1225d417007518 100644 (file)
@@ -1920,11 +1920,17 @@ int BC_WindowBase::unset_all_repeaters()
 //     return top_level->next_repeat_id++;
 // }
 
+XEvent *BC_WindowBase::new_xevent()
+{
+       XEvent *event = new XEvent;
+       memset(event, 0, sizeof(*event));
+       return event;
+}
 
 #ifndef SINGLE_THREAD
 int BC_WindowBase::arm_repeat(int64_t duration)
 {
-       XEvent *event = new XEvent;
+       XEvent *event = new_xevent();
        XClientMessageEvent *ptr = (XClientMessageEvent*)event;
        ptr->type = ClientMessage;
        ptr->message_type = RepeaterXAtom;
@@ -1944,7 +1950,7 @@ int BC_WindowBase::recieve_custom_xatoms(xatom_event *event)
 
 int BC_WindowBase::send_custom_xatom(xatom_event *event)
 {
-       XEvent *myevent = new XEvent;
+       XEvent *myevent = new_xevent();
        XClientMessageEvent *ptr = (XClientMessageEvent*)myevent;
        ptr->type = ClientMessage;
        ptr->message_type = event->message_type;
@@ -3307,7 +3313,7 @@ void BC_WindowBase::set_done(int return_value)
 #else // SINGLE_THREAD
                init_wait();
                if( !event_thread ) return;
-               XEvent *event = new XEvent;
+               XEvent *event = new_xevent();
                XClientMessageEvent *ptr = (XClientMessageEvent*)event;
                event->type = ClientMessage;
                ptr->message_type = SetDoneXAtom;
index 4d0e45679bfc9b3fd436849f19c657de301c23bc..d469f87032ac94141ce64283e28b823c219f8a13 100644 (file)
@@ -571,7 +571,7 @@ private:
        int trigger_tooltip();
        int untrigger_tooltip();
        void draw_tooltip();
-       int arm_repeat(int64_t duration);
+       static XEvent *new_xevent();
 // delete all repeater opjects for a close
        int unset_all_repeaters();
 
@@ -699,6 +699,7 @@ private:
 #ifndef SINGLE_THREAD
 // Array of repeaters for multiple repeating objects.
        ArrayList<BC_Repeater*> repeaters;
+       int arm_repeat(int64_t duration);
 #endif
 // Text for tooltip if one exists
        const char *tooltip_text;
index 24916156ada4286bdd3863db26409fa607d72a96..3f5e31cba515402e0f61747f68f7313abdf7b173 100644 (file)
@@ -358,8 +358,7 @@ const char* LensMode::to_text(int mode)
 //     int total = total_items();
 //     for(int i = 0; i < total; i++)
 //     {
-//             BC_MenuItem *item = get_item(0);
-//             remove_item(item);
+//             del_item();
 //     }
 // 
 // // Create current items
index 765ca95c07404369ef358d92a654cd13a02506c8..d2a838599873dd0bca27bd5590a4b55edf18ada8 100644 (file)
@@ -6021,6 +6021,41 @@ msgstr "Zeilen:"
 msgid "Texts:"
 msgstr "Texte:"
 
+#: cinelerra//swindow.C:202
+msgid ""
+"Adding Subtitles: quick \"How To\" (= or * indicates comment)\n"
+"*2345678901234567890123456789012345678901234567890123456789\n"
+"For regular DVD subtitles, put script in a text file. Lines can be any length but they will be broken up to fit according to some criteria below.\n"
+"Running text used as script lines will be broken into multilple lines.\n"
+"The target line length is 60 characters.\n"
+"Punctuation may be flagged to create an early line break.\n"
+"Single carriage return ends an individual script line.\n"
+"Double carriage return indicates the end of an entry.\n"
+"Whitespace at beginning or end of line is removed.\n"
+"You can edit the active line in the Line Text box.\n"
+"\n"
+"== A new entry is here for illustration purposes.\n"
+"*  Entry 2\n"
+"This is the second entry.\n"
+msgstr ""
+"Hinzufügen von Untertiteln: schnell \"How To\" (= oder * zeigt Kommentar)\n"
+"* 2345678901234567890123456789012345678901234567890123456789\n"
+"Für normalen DVD-Untertitel, setzen Skript in einer Textdatei. "
+"Linien können beliebig lang sein, aber sie werden "
+"aufgeteilt nach einigen Kriterien unten zu passen.\n"
+"Lauftext als Skriptzeilen verwendet\n"
+"wird in multilple Linien gebrochen werden.\n"
+"Die Zielzeilenlänge beträgt 60 Zeichen.\n"
+"Interpunktion kann eine frühe Zeilenumbruch zu erstellen markiert.\n"
+"Einzelwagenrücklauf endet eine individuelle Skriptzeile .\n"
+"Doppelwagenrücklauf zeigt das Ende eines Eintrags.\n"
+"Leerzeichen am Anfang oder Ende der Zeile wird entfernt.\n"
+"Sie können die aktive Zeile in der Zeile Textfeld bearbeiten.\n"
+"\n"
+"== Ein neuer Eintrag ist hier zur Illustration.\n"
+"*  Eintrag 2\n"
+"Dies ist der zweite Eintrag.\n"
+
 #: cinelerra//swindow.C:216
 msgid ": Subtitle"
 msgstr ": Untertitel"