packages feed

bustle 0.5.1 → 0.5.2

raw patch · 12 files changed

+383/−201 lines, 12 filesdep +gtk2hs-buildtoolsdep ~mtlsetup-changed

Dependencies added: gtk2hs-buildtools

Dependency ranges changed: mtl

Files

− Bustle/Gtk.hs
@@ -1,54 +0,0 @@-{--Bustle.Gtk: Stuff missing from the Gtk binding-Copyright © 2015 Will Thompson--This library is free software; you can redistribute it and/or-modify it under the terms of the GNU Lesser General Public-License as published by the Free Software Foundation; either-version 2.1 of the License, or (at your option) any later version.--This library is distributed in the hope that it will be useful,-but WITHOUT ANY WARRANTY; without even the implied warranty of-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU-Lesser General Public License for more details.--You should have received a copy of the GNU Lesser General Public-License along with this library; if not, write to the Free Software-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA--}-{-# LANGUAGE ForeignFunctionInterface #-}-module Bustle.Gtk-  ( b_windowSetTitlebar-  , b_headerBarSetSubtitle-  )-where--import Foreign.Ptr-import Foreign.ForeignPtr--import qualified System.Glib.GObject as GO-import System.Glib.Properties (objectSetPropertyMaybeString)-import Graphics.UI.Gtk---foreign import ccall "gtk_window_set_titlebar"-    gtk_window_set_titlebar :: Ptr GObject-                    -> Ptr GObject-                    -> IO ()---b_windowSetTitlebar :: (WindowClass window,-                        WidgetClass widget)-                    => window-                    -> widget-                    -> IO ()-b_windowSetTitlebar window titlebar =-    withForeignPtr (GO.unGObject (GO.toGObject window)) $ \pWindow ->-    withForeignPtr (GO.unGObject (GO.toGObject titlebar)) $ \pTitlebar ->-    gtk_window_set_titlebar pWindow pTitlebar--b_headerBarSetSubtitle :: WidgetClass headerBar -- BZZT-                       => headerBar-                       -> Maybe String-                       -> IO ()-b_headerBarSetSubtitle = objectSetPropertyMaybeString "subtitle"
Bustle/UI.hs view
@@ -38,7 +38,6 @@ import Bustle.Renderer import Bustle.Types import Bustle.Diagram-import Bustle.Gtk (b_windowSetTitlebar, b_headerBarSetSubtitle) import Bustle.Marquee (toString) import Bustle.Util import Bustle.UI.AboutDialog@@ -54,6 +53,7 @@  import qualified Control.Exception as C import System.Glib.GError (GError(..), failOnGError)+import System.Glib.Properties (objectSetPropertyMaybeString)  import Graphics.UI.Gtk @@ -346,7 +346,6 @@   window <- getW castToWindow "diagramWindow"   header <- getW castToWidget "header" -  io $ b_windowSetTitlebar window header   [openItem, openTwoItem] <- mapM (getW castToMenuItem) ["open", "openTwo"]   [headerNew, headerSave, headerExport] <- mapM (getW castToButton) ["headerNew", "headerSave", "headerExport"] @@ -486,7 +485,8 @@     writeIORef (wiLogDetails wi) (Just logDetails)     let (title, subtitle) = logWindowTitle logDetails     (wiWindow wi) `set` [ windowTitle := title ]-    b_headerBarSetSubtitle (wiHeaderBar wi) subtitle+    -- TODO: add to gtk2hs+    objectSetPropertyMaybeString "subtitle" (wiHeaderBar wi) subtitle  setPage :: MonadIO io         => WindowInfo
Bustle/UI/AboutDialog.hs view
@@ -46,9 +46,9 @@     dialog `set` [ aboutDialogName := __ "Bustle"                  , aboutDialogVersion := showVersion version                  , aboutDialogComments := __ "Someone's favourite D-Bus profiler"-                 , aboutDialogWebsite := "http://willthompson.co.uk/bustle"+                 , aboutDialogWebsite := "http://www.freedesktop.org/wiki/Software/Bustle/"                  , aboutDialogAuthors := authors-                 , aboutDialogCopyright := "© 2008–2014 Will Thompson, Collabora Ltd. and contributors"+                 , aboutDialogCopyright := "© 2008–2015 Will Thompson, Collabora Ltd. and contributors"                  , aboutDialogLicense := license                  , aboutDialogLogoIconName := Just "bustle"                  , windowModal := True
Bustle/UI/Recorder.hs view
@@ -108,17 +108,17 @@     loaderStateRef <- newMVar Map.empty     pendingRef <- newMVar []     let updateLabel µs body = do-        -- of course, modifyMVar and runStateT have their tuples back to front.-        m <- modifyMVar loaderStateRef $ \s -> do-            (m, s') <- runStateT (convert µs body) s-            return (s', m)+            -- of course, modifyMVar and runStateT have their tuples back to front.+            m <- modifyMVar loaderStateRef $ \s -> do+                (m, s') <- runStateT (convert µs body) s+                return (s', m) -        case m of-            Left e -> warn e-            Right message-              | isRelevant (deEvent message) -> do-                    modifyMVar_ pendingRef $ \pending -> return (message:pending)-              | otherwise -> return ()+            case m of+                Left e -> warn e+                Right message+                  | isRelevant (deEvent message) -> do+                        modifyMVar_ pendingRef $ \pending -> return (message:pending)+                  | otherwise -> return ()      handlerId <- monitor `on` monitorMessageLogged $ updateLabel     n <- newMVar (0 :: Int)
+ GetText.hs view
@@ -0,0 +1,220 @@+-- | This library extends the Distribution with internationalization support.+--+-- It performs two functions:+--+-- * compiles and installs PO files to the specified directory+--+-- * tells the application where files were installed to make it able+-- to bind them to the code+--+-- Each PO file will be placed to the+-- @{datadir}\/locale\/{loc}\/LC_MESSAGES\/{domain}.mo@ where:+--+--  [@datadir@] Usually @prefix/share@ but could be different, depends+--  on system.+--+--  [@loc@] Locale name (language code, two characters). This module+--  supposes, that each PO file has a base name set to the proper+--  locale, e.g. @de.po@ is the German translation of the program, so+--  this file will be placed under @{datadir}\/locale\/de@ directory+--+--  [@domain@] Program domain. A unique identifier of single+--  translational unit (program). By default domain will be set to the+--  package name, but its name could be configured in the @.cabal@ file.+--+-- The module defines following @.cabal@ fields:+--+--  [@x-gettext-domain-name@] Name of the domain. One ofmore+--  alphanumeric characters separated by hyphens or underlines. When+--  not set, package name will be used.+--+--  [@x-gettext-po-files@] List of files with translations. Could be+--  used a limited form of wildcards, e.g.: @x-gettext-po-files:+--  po/*.po@+--+--  [@x-gettext-domain-def@] Name of the macro, in which domain name+--  will be passed to the program. Default value is+--  @__MESSAGE_CATALOG_DOMAIN__@+--+--  [@x-gettext-msg-cat-def@] Name of the macro, in which path to the+--  message catalog will be passed to the program. Default value is+--  @__MESSAGE_CATALOG_DIR__@+--+-- The last two parameters are used to send configuration data to the+-- code during its compilation. The most common usage example is:+--+--+-- > ...+-- > prepareI18N = do+-- >    setLocale LC_ALL (Just "") +-- >    bindTextDomain __MESSAGE_CATALOG_DOMAIN__ (Just __MESSAGE_CATALOG_DIR__)+-- >    textDomain __MESSAGE_CATALOG_DOMAIN__+-- >+-- > main = do+-- >    prepareI18N+-- >    ...+-- >+-- > ...+--+--+-- /NOTE:/ files, passed in the @x-gettext-po-files@ are not+-- automatically added to the source distribution, so they should be+-- also added to the @extra-source-files@ parameter, along with+-- translation template file (usually @message.pot@)+--+-- /WARNING:/ sometimes, when only configuration targets changes, code+-- will not recompile, thus you should execute @cabal clean@ to+-- cleanup the build and restart it again from the configuration. This+-- is temporary bug, it will be fixed in next releases.+--+-- /TODO:/ this is lifted verbatim (modulo other /TODO/s) from hgettext's+-- Distribution.Simple.I18N.GetText partly to expose individual hooks and+-- partly to avoid the /cabal configure/-time dependency. For the latter,+-- see https://github.com/fpco/stackage/issues/746+-- ++module GetText +    (+    -- | /TODO:/ upstream exporting the individual hooks?+     installPOFiles,++    -- | /TODO:/ upstream generating GetText_foo.hs rather than exporting these?+     getDomainNameDefault,+     getPackageName,+     targetDataDir,++     installGetTextHooks,+     gettextDefaultMain+    ) where++import Distribution.Simple+import Distribution.Simple.Setup as S+import Distribution.Simple.LocalBuildInfo+import Distribution.PackageDescription+import Distribution.Simple.Configure+import Distribution.Simple.InstallDirs as I+import Distribution.Simple.Utils++import Language.Haskell.Extension++import Control.Monad+import Control.Arrow (second)+import Data.Maybe (listToMaybe, maybeToList, fromMaybe)+import Data.List (unfoldr,nub,null)+import System.FilePath+import System.Directory+import System.Process++-- | Default main function, same as+-- +-- > defaultMainWithHooks $ installGetTextHooks simpleUserHooks+-- +gettextDefaultMain :: IO ()+gettextDefaultMain = defaultMainWithHooks $ installGetTextHooks simpleUserHooks++-- | Installs hooks, used by GetText module to install+-- PO files to the system. Previous won't be disabled+--+installGetTextHooks :: UserHooks -- ^ initial user hooks+                    -> UserHooks -- ^ patched user hooks+installGetTextHooks uh = uh{+                           confHook = \a b -> +                                      (confHook uh) a b >>= +                                      return . updateLocalBuildInfo,++                           postInst = \a b c d -> +                                      (postInst uh) a b c d >> +                                      installPOFiles a b c d+                         }+++updateLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo+updateLocalBuildInfo l = +    let sMap = getCustomFields l+        [domDef, catDef] = map ($ sMap) [getDomainDefine, getMsgCatalogDefine]+        dom = getDomainNameDefault sMap (getPackageName l)+        tar = targetDataDir l+        [catMS, domMS] = map (uncurry formatMacro) [(domDef, dom), (catDef, tar)]+    in (appendCPPOptions [domMS,catMS] . appendExtension [EnableExtension CPP]) l++installPOFiles :: Args -> InstallFlags -> PackageDescription -> LocalBuildInfo -> IO ()+installPOFiles _ _ _ l = +    let sMap = getCustomFields l+        destDir = targetDataDir l+        dom = getDomainNameDefault sMap (getPackageName l)+        installFile file = do+          let fname = takeFileName file+          let bname = takeBaseName fname+          let targetDir = destDir </> bname </> "LC_MESSAGES"+          -- ensure we have directory destDir/{loc}/LC_MESSAGES+          createDirectoryIfMissing True targetDir+          system $ "msgfmt --output-file=" ++ +                     (targetDir </> dom <.> "mo") ++ +                     " " ++ file+    in do+      filelist <- getPoFilesDefault sMap+      -- copy all whose name is in the form of dir/{loc}.po to the+      -- destDir/{loc}/LC_MESSAGES/dom.mo+      -- with the 'msgfmt' tool+      mapM_ installFile filelist      ++forBuildInfo :: LocalBuildInfo -> (BuildInfo -> BuildInfo) -> LocalBuildInfo+forBuildInfo l f = +    let a = l{localPkgDescr = updPkgDescr (localPkgDescr l)}+        updPkgDescr x = x{library = updLibrary (library x), +                          executables = updExecs (executables x)}+        updLibrary Nothing = Nothing+        updLibrary (Just x) = Just $ x{libBuildInfo = f (libBuildInfo x)}+        updExecs x = map updExec x+        updExec x = x{buildInfo = f (buildInfo x)}+    in a++appendExtension :: [Extension] -> LocalBuildInfo -> LocalBuildInfo+appendExtension exts l = +    forBuildInfo l updBuildInfo+    where updBuildInfo x = x{defaultExtensions = updExts (defaultExtensions x)}+          updExts s = nub (s ++ exts)++appendCPPOptions :: [String] -> LocalBuildInfo -> LocalBuildInfo+appendCPPOptions opts l = +    forBuildInfo l updBuildInfo+    where updBuildInfo x = x{cppOptions = updOpts (cppOptions x)}+          updOpts s = nub (s ++ opts)++formatMacro name value = "-D" ++ name ++ "=" ++ (show value)++targetDataDir :: LocalBuildInfo -> FilePath+targetDataDir l = +    let dirTmpls = installDirTemplates l+        prefix' = prefix dirTmpls+        data' = datadir dirTmpls+        dataEx = I.fromPathTemplate $ I.substPathTemplate [(PrefixVar, prefix')] data'+    in dataEx ++ "/locale"++getPackageName :: LocalBuildInfo -> String+getPackageName = fromPackageName . packageName . localPkgDescr+    where fromPackageName (PackageName s) = s++getCustomFields :: LocalBuildInfo -> [(String, String)]+getCustomFields = customFieldsPD . localPkgDescr++findInParametersDefault :: [(String, String)] -> String -> String -> String+findInParametersDefault al name def = (fromMaybe def . lookup name) al++getDomainNameDefault :: [(String, String)] -> String -> String+getDomainNameDefault al d = findInParametersDefault al "x-gettext-domain-name" d++getDomainDefine :: [(String, String)] -> String+getDomainDefine al = findInParametersDefault al "x-gettext-domain-def" "__MESSAGE_CATALOG_DOMAIN__"++getMsgCatalogDefine :: [(String, String)] -> String+getMsgCatalogDefine al = findInParametersDefault al "x-gettext-msg-cat-def" "__MESSAGE_CATALOG_DIR__"++getPoFilesDefault :: [(String, String)] -> IO [String]+getPoFilesDefault al = toFileList $ findInParametersDefault al "x-gettext-po-files" ""+    where toFileList "" = return []+          toFileList x = liftM concat $ mapM matchFileGlob $ split' x+          -- from Blow your mind (HaskellWiki)+          -- splits string by newline, space and comma+          split' x = concatMap lines $ concatMap words $ unfoldr (\b -> fmap (const . (second $ drop 1) . break (==',') $ b) . listToMaybe $ b) x+
LICENSE.bundled-libraries view
@@ -1,6 +1,6 @@ Shipping these libraries in the tarball is monstrous, and I'm sorry. I just wanted to ship this thing. Anyway, these libraries are slurped right out of the-Debian packages on the system the tarball was built on. Here are some licenses:+OS packages on the system the tarball was built on. Here are some licenses:  libffi: @@ -68,7 +68,7 @@     You should have received a copy of the GNU Lesser General Public License     along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/. -The source code is available from http://willthompson.co.uk/bustle/releases/.+The source code is available from http://www.freedesktop.org/software/bustle/ Your complimentary copy of the GNU Lesser General Public License follows:                     GNU LESSER GENERAL PUBLIC LICENSE
Makefile view
@@ -112,6 +112,7 @@ 	./ldd-me-up.sh $(TARBALL_FULL_DIR)/bin/bustle \ 		| xargs -I XXX cp XXX $(TARBALL_FULL_DIR)/lib 	cd $(TARBALL_PARENT_DIR) && tar cjf $(TARBALL) $(TARBALL_DIR)+	rm -r $(TARBALL_FULL_DIR)  maintainer-update-messages-pot: 	find Bustle -name '*.hs' -print0 | xargs -0 hgettext -k __ -o po/messages.pot@@ -122,3 +123,6 @@ 	git tag -s -m 'Bustle '`cat dist/build/autogen/version.txt` \ 		bustle-`cat dist/build/autogen/version.txt` 	make maintainer-binary-tarball++.travis.yml: bustle.cabal make_travis_yml.hs+	./make_travis_yml.hs $< libpcap-dev libgtk-3-dev libcairo2-dev happy-1.19.4 alex-3.1.3 > $@
NEWS.md view
@@ -1,3 +1,11 @@+Bustle 0.5.2 (2015-08-18)+-------------------------++* No functional changes!+* Update all links to <http://www.freedesktop.org/wiki/Software/Bustle/>+* Remove external dependencies from Cabal build script for the benefit+  of Stackage and Travis-CI.  <https://github.com/fpco/stackage/issues/746>+ Bustle 0.5.1 (2015-06-28) ------------------------- @@ -200,8 +208,8 @@ While we're here, Bustle's git repository has moved to freedesktop.org, and it now has a bug tracker there too. Browse the source at <http://cgit.freedesktop.org/bustle/>; see open bugs at-<http://wjt.me.uk/bustle/bugs>; file new ones at-<http://wjt.me.uk/bustle/new-bug>. Astonishing!+<https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&list_id=549676&product=Bustle&query_format=advanced>; file new ones at+<https://bugs.freedesktop.org/enter_bug.cgi?product=Bustle>. Astonishing!  * The viewer is now much more tolerant of inconsistencies in log files.   (Thanks to Marco Barisione for the [bug report][fdo35297].)
README.md view
@@ -44,4 +44,4 @@ More information ================ -See <http://wjt.me.uk/bustle/>.+See <http://www.freedesktop.org/wiki/Software/Bustle/>.
Setup.hs view
@@ -1,11 +1,9 @@ {-# OPTIONS_GHC -Wall #-}-import Data.Maybe (fromMaybe) import System.FilePath ( (</>), (<.>) )  import Distribution.PackageDescription import Distribution.Simple import Distribution.Simple.BuildPaths ( autogenModulesDir )-import Distribution.Simple.InstallDirs as I import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Setup as S import Distribution.Simple.Utils@@ -14,7 +12,7 @@ import Distribution.ModuleName (ModuleName) import qualified Distribution.ModuleName as ModuleName -import qualified Distribution.Simple.I18N.GetText as GetText+import qualified GetText as GetText  main :: IO () main = defaultMainWithHooks $ installBustleHooks simpleUserHooks@@ -31,13 +29,13 @@ installBustleHooks :: UserHooks                    -> UserHooks installBustleHooks uh = uh-  { postInst = postInst gtuh+  { postInst = \a b c d -> do+        postInst uh a b c d+        GetText.installPOFiles a b c d   , buildHook = \pkg lbi hooks flags -> do         writeGetTextConstantsFile pkg lbi flags         buildHook uh pkg lbi hooks flags   }-  where-    gtuh = GetText.installGetTextHooks uh   writeGetTextConstantsFile :: PackageDescription -> LocalBuildInfo -> BuildFlags -> IO ()@@ -90,24 +88,7 @@         "getMessageCatalogDir = catchIO (getEnv \"" ++ fixedPackageName pkg ++ "_localedir\") (\\_ -> return messageCatalogDir)\n"      sMap = customFieldsPD (localPkgDescr lbi)-    dom = getDomainNameDefault sMap (getPackageName lbi)-    tar = targetDataDir lbi+    dom = GetText.getDomainNameDefault sMap (GetText.getPackageName lbi)+    tar = GetText.targetDataDir lbi  -- Cargo-culted from hgettext-findInParametersDefault :: [(String, String)] -> String -> String -> String-findInParametersDefault al name def = (fromMaybe def . lookup name) al--getPackageName :: LocalBuildInfo -> String-getPackageName = fromPackageName . packageName . localPkgDescr-    where fromPackageName (PackageName s) = s--getDomainNameDefault :: [(String, String)] -> String -> String-getDomainNameDefault al d = findInParametersDefault al "x-gettext-domain-name" d--targetDataDir :: LocalBuildInfo -> FilePath-targetDataDir l =-    let dirTmpls = installDirTemplates l-        prefix' = prefix dirTmpls-        data' = datadir dirTmpls-        dataEx = I.fromPathTemplate $ I.substPathTemplate [(PrefixVar, prefix')] data'-    in dataEx ++ "/locale"
bustle.cabal view
@@ -1,13 +1,15 @@ Name:           bustle Category:       Network, Desktop-Version:        0.5.1-Cabal-Version:  >= 1.8+Version:        0.5.2+Cabal-Version:  >= 1.18+Tested-With:    GHC >= 7.8.4 && < 7.11 Synopsis:       Draw sequence diagrams of D-Bus traffic Description:    Draw sequence diagrams of D-Bus traffic License:        OtherLicense License-file:   LICENSE Author:         Will Thompson <will@willthompson.co.uk> Maintainer:     Will Thompson <will@willthompson.co.uk>+Homepage:       http://www.freedesktop.org/wiki/Software/Bustle/ Data-files:     data/dfeet-method.png,                 data/dfeet-signal.png,                 data/bustle.ui,@@ -34,6 +36,10 @@                   , ldd-me-up.sh                   , LICENSE.bundled-libraries +                  -- inlined copy of the Cabal hooks from hgettext;+                  -- see https://github.com/fpco/stackage/issues/746+                  , GetText.hs+                   -- wow many translate                   , po/*.po                   , po/*.pot@@ -66,11 +72,17 @@   Description:    Build with the multi-threaded runtime   Default:        True +Flag WithGtk2HsBuildTools+  Description:    Build-depend on gtk2hs-buildtools. They aren't (currently)+                  used to build Bustle itself but are needed to build+                  dependencies like gtk3, which for whatever reason do not+                  Build-Depend on the tools.+  Default:        False+ Executable bustle   Main-is:       Bustle.hs   Other-modules: Bustle.Application.Monad                , Bustle.Diagram-               , Bustle.Gtk                , Bustle.Loader                , Bustle.Loader.OldSkool                , Bustle.Loader.Pcap@@ -94,13 +106,14 @@                , Bustle.Upgrade                , Bustle.Util                , Bustle.VariantFormatter+  default-language: Haskell2010   Ghc-options: -Wall                -fno-warn-unused-do-bind   if flag(threaded)     ghc-options: -threaded   C-sources: c-sources/pcap-monitor.c+  cc-options: -fPIC   pkgconfig-depends: glib-2.0 >= 2.26-   Build-Depends: base >= 4 && < 5                , bytestring                , cairo@@ -112,7 +125,7 @@                , gio                , gtk3                , hgettext >= 0.1.5-               , mtl+               , mtl >= 2.2.1                , pango                , parsec                , pcap@@ -121,6 +134,9 @@                , text                , time +  if flag(WithGtk2HsBuildTools)+    Build-Depends: gtk2hs-buildtools+ Executable test-monitor   if flag(InteractiveTests)     buildable: True@@ -129,9 +145,11 @@    main-is: tests/Monitor.hs   other-modules: Bustle.Monitor+  default-language: Haskell2010   if flag(threaded)     Ghc-options: -threaded   C-sources: c-sources/pcap-monitor.c+  cc-options: -fPIC   pkgconfig-depends: glib-2.0   Build-Depends: base >= 4 && < 5                , bytestring@@ -158,6 +176,7 @@     buildable: False    main-is: Test/DumpMessages.hs+  default-language: Haskell2010   Build-Depends: base                , bytestring                , containers@@ -170,6 +189,7 @@     type: exitcode-stdio-1.0     main-is: Test/PcapCrash.hs     other-modules: Bustle.Loader.Pcap+    default-language: Haskell2010     Build-Depends: base                  , bytestring                  , containers@@ -189,6 +209,7 @@     type: exitcode-stdio-1.0     main-is: Test/Renderer.hs     other-modules: Bustle.Renderer+    default-language: Haskell2010     Build-Depends: base                  , cairo                  , containers
data/bustle.ui view
@@ -7,6 +7,105 @@     <property name="default_height">700</property>     <property name="icon-name">bustle</property>     <property name="title" translatable="yes">Bustle</property>+    <child type="titlebar">+        <object class="GtkHeaderBar" id="header">+          <property name="visible">True</property>+          <property name="show-close-button">True</property>++          <child>+            <object class="GtkMenuButton" id="headerOpen">+              <property name="visible">True</property>+              <property name="sensitive">True</property>+              <property name="tooltip_text" translatable="yes">Open an existing log</property>+              <property name="popup">openMenu</property>+              <style>+                <class name="image-button"/>+              </style>+              <child>+                <object class="GtkImage">+                  <property name="visible">True</property>+                  <property name="icon-name">document-open-symbolic</property>+                  <property name="icon-size">1</property>+                </object>+              </child>+            </object>+            <packing>+              <property name="pack-type">GTK_PACK_START</property>+            </packing>+          </child>++          <!-- TODO: media-record-symbolic -->+          <child>+            <object class="GtkButton" id="headerNew">+              <property name="visible">True</property>+              <property name="label" translatable="yes">Record</property>+              <property name="tooltip_text" translatable="yes">Record a new log</property>+            </object>+          </child>++          <child>+            <object class="GtkMenuButton">+              <property name="visible">True</property>+              <property name="popup">filterStatsEtc</property>+              <style>+                <class name="image-button"/>+              </style>+              <child>+                <object class="GtkImage">+                  <property name="visible">True</property>+                  <property name="icon-name">open-menu-symbolic</property>+                  <property name="icon-size">1</property>+                </object>+              </child>+            </object>+            <packing>+              <property name="pack-type">end</property>+            </packing>+          </child>++          <child>+            <object class="GtkButton" id="headerExport">+              <property name="visible">True</property>+              <property name="sensitive">False</property>+              <property name="tooltip_text" translatable="yes">Export as PDF</property>+              <style>+                <class name="image-button"/>+              </style>+              <child>+                <object class="GtkImage">+                  <property name="visible">True</property>+                  <property name="icon-name">document-send-symbolic</property>+                  <property name="icon-size">1</property>+                </object>+              </child>+            </object>+            <packing>+              <property name="pack-type">end</property>+            </packing>+          </child>++          <child>+            <object class="GtkButton" id="headerSave">+              <property name="visible">True</property>+              <property name="sensitive">False</property>+              <property name="tooltip_text" translatable="yes">Save</property>+              <style>+                <class name="image-button"/>+              </style>+              <child>+                <object class="GtkImage">+                  <property name="visible">True</property>+                  <property name="icon-name">document-save-symbolic</property>+                  <property name="icon-size">1</property>+                </object>+              </child>+            </object>+            <packing>+              <property name="pack-type">end</property>+            </packing>+          </child>+        </object>+    </child>     <child>       <object class="GtkVBox" id="box1">         <property name="visible">True</property>@@ -327,103 +426,6 @@           </packing>         </child>       </object>-    </child>-  </object>-  <object class="GtkHeaderBar" id="header">-    <property name="visible">True</property>-    <property name="show-close-button">True</property>--    <child>-      <object class="GtkMenuButton" id="headerOpen">-        <property name="visible">True</property>-        <property name="sensitive">True</property>-        <property name="tooltip_text" translatable="yes">Open an existing log</property>-        <property name="popup">openMenu</property>-        <style>-          <class name="image-button"/>-        </style>-        <child>-          <object class="GtkImage">-            <property name="visible">True</property>-            <property name="icon-name">document-open-symbolic</property>-            <property name="icon-size">1</property>-          </object>-        </child>-      </object>-      <packing>-        <property name="pack-type">GTK_PACK_START</property>-      </packing>-    </child>--    <!-- TODO: media-record-symbolic -->-    <child>-      <object class="GtkButton" id="headerNew">-        <property name="visible">True</property>-        <property name="label" translatable="yes">Record</property>-        <property name="tooltip_text" translatable="yes">Record a new log</property>-      </object>-    </child>--    <child>-      <object class="GtkMenuButton">-        <property name="visible">True</property>-        <property name="popup">filterStatsEtc</property>-        <style>-          <class name="image-button"/>-        </style>-        <child>-          <object class="GtkImage">-            <property name="visible">True</property>-            <property name="icon-name">open-menu-symbolic</property>-            <property name="icon-size">1</property>-          </object>-        </child>-      </object>-      <packing>-        <property name="pack-type">end</property>-      </packing>-    </child>--    <child>-      <object class="GtkButton" id="headerExport">-        <property name="visible">True</property>-        <property name="sensitive">False</property>-        <property name="tooltip_text" translatable="yes">Export as PDF</property>-        <style>-          <class name="image-button"/>-        </style>-        <child>-          <object class="GtkImage">-            <property name="visible">True</property>-            <property name="icon-name">document-send-symbolic</property>-            <property name="icon-size">1</property>-          </object>-        </child>-      </object>-      <packing>-        <property name="pack-type">end</property>-      </packing>-    </child>--    <child>-      <object class="GtkButton" id="headerSave">-        <property name="visible">True</property>-        <property name="sensitive">False</property>-        <property name="tooltip_text" translatable="yes">Save</property>-        <style>-          <class name="image-button"/>-        </style>-        <child>-          <object class="GtkImage">-            <property name="visible">True</property>-            <property name="icon-name">document-save-symbolic</property>-            <property name="icon-size">1</property>-          </object>-        </child>-      </object>-      <packing>-        <property name="pack-type">end</property>-      </packing>     </child>   </object>