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 +0/−54
- Bustle/UI.hs +3/−3
- Bustle/UI/AboutDialog.hs +2/−2
- Bustle/UI/Recorder.hs +10/−10
- GetText.hs +220/−0
- LICENSE.bundled-libraries +2/−2
- Makefile +4/−0
- NEWS.md +10/−2
- README.md +1/−1
- Setup.hs +6/−25
- bustle.cabal +26/−5
- data/bustle.ui +99/−97
− 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>