Archive

Author Archive

Extract album art from MP3 files

May 7th, 2016 No comments

Recently I needed to extract the album art from an MP3 file and came across a really easy to use command line utility called eyeD3 to do just that (among other things). Here is how you can extract all of the album art from a file MyFile.mp3 into a directory called Output.

1) Install eyeD3

sudo apt-get install eyeD3

2) Extract all embedded album art from the file

eyeD3 --write-images=Output/ MyFile.mp3

Pretty simple!




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

KWLUG: Docker Tutorial (2016-04)

April 23rd, 2016 No comments

This is a podcast presentation from the Kitchener Waterloo Linux Users Group on the topic of Docker published on April 5th 2016. You can find the original Kitchener Waterloo Linux Users Group post here.

Read more…




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

KWLUG: Mastering Photo DVDs, KDEnlive (2016-03)

March 8th, 2016 No comments

This is a podcast presentation from the Kitchener Waterloo Linux Users Group on the topic of Mastering Photo DVDs, KDEnlive published on March 8th 2016. You can find the original Kitchener Waterloo Linux Users Group post here.

Read more…




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Murdering misbehaving applications with xkill

March 5th, 2016 No comments

Have you ever had a window in Linux freeze on you and no matter how many times you tried to close it, it just wouldn’t go away? Then when you try and find the process in System Monitor (or the like) you can’t seem to identify it for whatever reason?

Thankfully there is a really easy to use command that lets you simply click on the offending window and POOF!… it goes away instantly. So how does it work? Let’s say you have a window that is frozen like this

As long as you can see it you can kill it!

As long as you can see it you can xkill it!

First open up a new terminal window and type the command

xkill

and hit Enter. This will then tell you to simply click on the window you want to kill:

Select the window whose client you wish to kill with button 1….

Next it is as simple as actually clicking on the frozen window and you can say goodbye to your problem. Happy xkill-ing 🙂

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Limit bandwidth used by a command in Linux

February 28th, 2016 No comments

If you’ve ever wanted to run a bandwidth intensive command (for example downloading system updates) but limit how much of the available bandwidth it can actually use then trickle may be what you’re after.

Simply install it using

sudo apt-get install trickle

and then you can use it with the following syntax

trickle -d X -u Y command

where X is download limit in KB/s, Y is the upload limit in KB/s and command is the process you want to start limited to these bandwidth constraints. For example if I wanted to start a download of the latest (as of this writing) AMD64 VirtualBox for Ubuntu using wget but limit it to only using 50KB/s down and 20KB/s up then I would run

trickle -d 50 -u 20 wget http://download.virtualbox.org/virtualbox/5.0.14/virtualbox-5.0_5.0.14-105127~Ubuntu~trusty_amd64.deb

I should point out that trickle does it’s best to limit the bandwidth to what you select but often won’t be exact in how it does this. Either way it is another cool little tool for your Linux toolbox.

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Linux, Tyler B Tags:

A nifty utility to limit CPU usage on Linux

February 27th, 2016 No comments

If you want to run a command that you know is going to use quite a bit of CPU but you don’t want it to completely take over your system there is a really neat utility that can help you out. It’s called cpulimit and it does exactly what you think it would.

The basic usage is this:

cpulimit -l XX command

where XX is the CPU % you want to limit the process to and command is the process you want to run. So for example let’s say you wanted Firefox to only ever use 30% of your CPU you would simply start it from a terminal like this:

cpulimit -l 30 firefox

You can even limit it based on CPU cores instead of overall CPU usage if you want using the -c flag instead of the -l flag.

If you want more advanced features you could use something like cgroups but for simple stuff cpulimit seems to work very well.

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Tyler B Tags:

Setting up Syncthing to share files on Linux

February 21st, 2016 No comments

Syncthing is a file sharing application that lets you easily, and securely, share files between computers without having to store them on a third party server. It is most analogous to BitTorrent Sync (BTS) but whereas BTS is somewhat undocumented and closed source, Syncthing is open source and uses an open protocol that can be independently verified.

This is going to be a basic guide to configure Syncthing to sync a folder between multiple computers. I’m also going to configure these to start automatically when the system starts up and run Syncthing in the background so it doesn’t get in your way if you don’t want to see it.

Download and Install

While it may be possible to get Syncthing from your distribution’s repositories I prefer to grab it right from the source. So for example you can grab the appropriate version for your Linux computer (for example the 64 bit syncthing-linux-amd64-v0.12.19.tar.gz download) right from their website.

Extract the contents to a new folder in your home directory (or a directory wherever you want it to live). One important thing to note is that you want whatever user will be running the program, for example your user account, to have write access to that folder so that Syncthing can auto-update itself. For example you could extract the files to ~/syncthing/ to make things easy.

To start Syncthing all you need to do is execute the syncthing binary in that directory. If you want to configure syncthing to start without also starting up the browser you can simply run it using the -no-browser flag or by changing this behaviour in the settings.

If you are on Debian, Ubuntu or derivatives (such as Linux Mint) there is also an official repository you can add. The steps can be found here but I’ve re-listed them below for completeness sake:

# Add the release PGP keys:
curl -s https://syncthing.net/release-key.txt | sudo apt-key add -

# Add the "release" channel to your APT sources:
echo "deb http://apt.syncthing.net/ syncthing release" | sudo tee /etc/apt/sources.list.d/syncthing.list

# Update and install syncthing:
sudo apt-get update
sudo apt-get install syncthing

This will install syncthing to /usr/bin/syncthing. In order to specify a configuration location you can pass the -home flag which would look something like this:

./usr/bin/syncthing -home="/home/{YOUR USER ACCOUNT}/.config/syncthing"

So to set up syncthing to start automatically without the browser using the specified configuration you would simply add this to your list of startup applications:

/usr/bin/syncthing -no-browser -home="/home/{YOUR USER ACCOUNT}/.config/syncthing"

There are plenty of ways to configure Syncthing to startup automatically but the one described above is a pretty universal method. If you would rather integrate it with your system using runit/systemd/upstart just take a look at the etc folder in the tar.gz.

Here is an example of my Linux Mint configuration in the Startup Applications control panel using the command listed above:

It's easy enough to get Syncthing started

It’s easy enough to get Syncthing started

Configure Syncthing

Once Syncthing is running you should be able to browse to it’s interface by going to http://localhost:8080. From this point forward I’m going to assume you want to sync between two computers which I will refer to as Computer 1 and Computer 2.

First let’s start by letting Computer 1 know about Computer 2 and vice versa.

  1. On Computer 1 click Actions > Show ID. Copy the long device identification text (it will look like a series of XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX-…).
  2. On Computer 2 click Add Device and enter the copied Device ID and give it a Device Name.
  3. Back on Computer 1 you may notice a New Device notification which will allow you to easily add Computer 2 there as well. If you do not see this notification simply follow the steps above but in reverse, copying Computer 2’s device ID to Computer 1.
Once both computers know about each other they can begin syncing!

Once both computers know about each other they can begin syncing!

In order to share a folder you need to start by adding it to the Syncthing on one of the two computers. To make it simple I will do this on Computer 1. Click Add Folder and you will see a popup asking for a bunch of information. The important ones are:

  • Folder ID: This is the name or label of the shared folder. It must be the same on all computers taking part in the share.
  • Folder Path: This is where you want it to store the files on the local computer. For example on Computer 1 I might wan this to be ~/Sync/MyShare but on Computer 2 it could be /syncthing/shares/stuff.
  • Share With Devices: These are the computers you want to share this folder with.

So for example let’s say I want to share a folder called “CoolThings” and I wanted it to live in ~/Sync/CoolThings on Computer 1. Filling in this information would look like this:

syncthing_folder_setup

Finally to share it with Computer 2 I would check Computer 2 under the Share With Devices section.

Once done you should see a new notification on Computer 2 asking if you want to add the newly shared folder there as well.

Syncthing alerts you to newly shared folders

Syncthing alerts you to newly shared folders

Once done the folder should be shared and anything you put into the folder on either computer will be automatically synchronized on the other.

If you would like to add a third or fourth computer just follow the steps above again. Pretty easy no?

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

CoreGTK 3.10.2 Released!

February 19th, 2016 No comments

The next version of CoreGTK, version 3.10.2, has been tagged for release today.

Highlights for this release:

  • This is a bug fix release.
  • Corrected issue with compiling CoreGTK on OS X.

CoreGTK is an Objective-C language binding for the GTK+ widget toolkit. Like other “core” Objective-C libraries, CoreGTK is designed to be a thin wrapper. CoreGTK is free software, licensed under the GNU LGPL.

You can find more information about the project here and the release itself here.

This post originally appeared on my personal website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Turn your computer into your own Chromecast

February 7th, 2016 No comments

Google Chromecasts are neat little devices that let you ‘cast’ (send) media from your phone or tablet to play on your TV. If however, you already have a computer hooked up to your TV you don’t need to go out and buy a new device simply to have the same functionality. Instead you can install the excellent Leapcast program and accomplish the same functionality.

Leapcast works on all major operating systems – Windows, Mac and Linux – but for the purposes of this post I’m going to be focusing on how to set it up on a Debian based Linux distribution.

Step 1) Install Google Chrome browser

The Google Chrome browser is required for Leapcast to work correctly so the first thing you’ll need to do is head over to the download page and install it.

Step 2) Install miscellaneous required applications and libraries

Leapcast also requires a few extra tools and libraries to be installed.

sudo apt-get install virtualenvwrapper python-pip python-twisted-web python2.7-dev

Step 3) Download Leapcast

Head over to the GitHub page and download the zip of the latest Leapcast code. Alternatively you can also install git and use it to grab the latest code that way:

git clone https://github.com/dz0ny/leapcast.git

Step 4) Install Leapcast

In the leapcast directory run the following command. Note you may need to be root in order to do this without error.

sudo python setup.py develop

Step 5) Run Leapcast

Now that Leapcast is install you should be able to run it. Simply open a terminal and type

leapcast

There are some other neat options you can pass it as well. For example if you want your computer to show up as, say, TheLinuxExperiment when someone goes to cast to it simply pass the –name parameter.

leapcast --name TheLinuxExperiment

Happy casting!




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Listener Feedback podcast episode 52: Silence – L’autre Endroit

January 24th, 2016 No comments

Listener Feedback podcast is a royalty free and Creative Commons music podcast. This episode, titled “Episode 52: Full Album – Silence – L’autre Endroit” was released on Sunday January 24th, 2016. To suggest artists and albums that should be featured you can send an e-mail to contact@listenerfeedback.net or message @LFpodcast on Twitter.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Open formats are… the best formats?

January 17th, 2016 2 comments

Over the past few years there has been a big push to replace proprietary formats with open formats. For example Open Document Format and Office Open XML have largely replaced the legacy binary formats, we’re now seeing HTML5 + JavaScript supplant Silverlight and Java applets, and even the once venerable Flash is on its deathbed.

This of course all makes sense. We’re now in an era where the computing platforms, be it Microsoft Windows, Apple OS X, Android, iOS, Linux, etc., simply don’t command the individual market shares (or at least mind shares) that they once used to. Things are… more diversified now. And while they may not matter to the user the underlying differences in technologies certainly matter to the developer. This is one of the many reasons you see lots of movement to open formats where the same format can be implemented, relatively easily, on all of the aforementioned platforms.

So then the question must be asked: does this trend mean that open formats are the best formats? That is obviously quite a simple question to a deep (and perhaps subjective) subject so perhaps it’s better to look at it from a user adoption perspective. Does being an open format, given all of its advantages, translate to market adoption? There the answer is not as clear.

Open by example

Let’s take a look a few instances where a clear format winner exists and see if it is an open format or a closed/proprietary format.

Documents

When it comes to documents the Open Document Format and Open Office XML have largely taken over. This has been driven largely by Microsoft making Office Open XML the default file format in all versions of Microsoft Office since 2007. Additionally many governments and organizations around the world have standardized on the use of Open Document Format. That said older Microsoft Office binary formats (i.e. .doc, .xls, etc.) are still widely in use.

Verdict: open formats have largely won out.

Audio

For the purposes of the “audio” category let’s consider simply the audio codec that most people use to consume their music. In that regard MP3 is still the absolute dominant format. While it is somewhat encumbered by patents you will hardly find a single device out there that doesn’t support it. This is true even when there are better lossy compression formats (including the proprietary AAC or open Ogg Vorbis) as well as lossless formats like FLAC.

Verdict: the closed/proprietary MP3 format is the de facto standard.

Video

Similarly for the “video” category I’ll only be focusing on the codecs. While there are plenty of open video formats (Theora, WebM, etc.) they are not nearly as well supported as the proprietary formats like MPEG-2, H.264, etc. Additionally the open formats (in general) don’t have quite as good quality vs size ratios as the proprietary ones which is often while you’ll see websites using them in order to save on bandwidth.

Verdict: closed/proprietary formats have largely won out.

File Compression

Compression is something that most people consider more as an algorithm than a format which is why I’ll be focusing on the compressed file container formats for this category. In that regard the ZIP file format is by far the most common. It has native support in every modern operating system and offers decent compression. Other open formats, such as 7-Zip, offer better performance and even some proprietary formats, like RAR, have seen widespread use but for the most part ZIP is the go-to format. What muddies the waters here a bit is that the base ZIP format is open but some of the features added later on were not. However the majority of uses are based on the open standards.

Verdict: the open zip format is the most widely used standard.

Native Applications vs Web Apps

While applications may not, strictly speaking, be a format it does seem to be the case that every year there are stories about how Web Apps will soon replace Native Applications. So far however the results are a little mixed with e-mail being a perfect example of this paradox. For personal desktop e-mail web apps, mostly Gmail and the like, have largely replaced native applications like Microsoft Outlook and Thunderbird. On mobile however the majority of users still access their e-mail via native “apps”. And even then in enterprises the majority of e-mail usage is still done via native applications. I’m honestly not sure which will eventually win out, if either, but for now let’s call it a tie.

Verdict: tie.

The answer to the question is…

Well just on the five quick examples above we’ve got wins for 2 open formats, 2 closed/proprietary formats and one tie. So clearly based on market adoption we’re at a stand still.

Personally I’d prefer if open formats would take over because then I wouldn’t have to worry about my device supporting the format in question or not. Who knows, maybe by next year we’ll see one of the two pull ahead.

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

KWLUG: Mageia Linux, Tax Software (2016-01)

January 12th, 2016 No comments

This is a podcast presentation from the Kitchener Waterloo Linux Users Group on the topic of Mageia Linux, Tax Software published on January 5th 2016. You can find the original Kitchener Waterloo Linux Users Group post here.

Read more…




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Linux, Podcast, Tyler B Tags: ,

KWLUG: GNU Social (2015-12)

January 12th, 2016 No comments

This is a podcast presentation from the Kitchener Waterloo Linux Users Group on the topic of GNU Social published on December 8th 2015. You can find the original Kitchener Waterloo Linux Users Group post here.

Read more…




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Linux, Podcast, Tyler B Tags: ,

Listener Feedback podcast episode 51: Other Nosies – S.L.A.S.H

January 10th, 2016 No comments

Listener Feedback podcast is a royalty free and Creative Commons music podcast. This episode, titled “Episode 51: Full Album – Other Noises – S.L.A.S.H” was released on Sunday January 10th, 2016. To suggest artists and albums that should be featured you can send an e-mail to contact@listenerfeedback.net or message @LFpodcast on Twitter.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Listener Feedback podcast episode 50: Tab – Dead Poets: The Village Idiots

December 27th, 2015 No comments

Listener Feedback podcast is a royalty free and Creative Commons music podcast. This episode, titled “Episode 50: Full Album – Tab – Dead Poets: The Village Idiots” was released on Sunday December 27th, 2015. To suggest artists and albums that should be featured you can send an e-mail to contact@listenerfeedback.net or message @LFpodcast on Twitter.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Listener Feedback podcast episode 49: Final Round – None Of Us Will Ever Leave A Legacy

December 13th, 2015 No comments

Listener Feedback podcast is a royalty free and Creative Commons music podcast. This episode, titled “Episode 49: Full Album – Final Round – None Of Us Will Ever Leave A Legacy” was released on Sunday December 13th, 2015. To suggest artists and albums that should be featured you can send an e-mail to contact@listenerfeedback.net or message @LFpodcast on Twitter.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Let’s write a very simple text editor in CoreGTK

December 5th, 2015 No comments

In this post I’ll quickly show how you can write a very simple text editor using CoreGTK. This example is purposely very basic, has no real error handling and few features but it does show how to use CoreGTK in various ways.

To start with I quickly threw something together in GLADE (which if you aren’t aware is an excellent drag and drop GUI editor for GTK+).

coregtk_glade

Very basic shell in GLADE

Next I created a SimpleTextEditor class that will house the majority of my logic and stubbed out my callbacks and methods.

@interface SimpleTextEditor : NSObject
{
    CGTKTextView *txtView;
    CGTKWidget *window;
}

-(void)show;

// Callbacks
-(void)winMain_Destroy;
-(void)btnNew_Clicked;
-(void)btnOpen_Clicked;
-(void)btnSave_Clicked;

// Helper methods to deal with the text view
-(NSString *)getText;
-(void)setText:(NSString *)text;

@end

Now the fun part begins: filling in the implementation of the methods. First create the init and dealloc methods:

-(id)init
{
    self = [super init];
    
    if(self)
    {
        CGTKBuilder *builder = [[CGTKBuilder alloc] init];
        if(![builder addFromFileWithFilename:@"gui.glade" andErr:NULL])
        {
            NSLog(@"Error loading GUI file");
            return nil;
        }
        
        NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:
            [CGTKCallbackData withObject:self andSEL:@selector(winMain_Destroy)], @"winMain_Destroy",
            [CGTKCallbackData withObject:self andSEL:@selector(btnNew_Clicked)], @"btnNew_Clicked",
            [CGTKCallbackData withObject:self andSEL:@selector(btnOpen_Clicked)], @"btnOpen_Clicked",
            [CGTKCallbackData withObject:self andSEL:@selector(btnSave_Clicked)], @"btnSave_Clicked",
            nil];
        
        [CGTKBaseBuilder connectSignalsToObjectsWithBuilder:builder andSignalDictionary:dic];
        
        // Get a reference to the window
        window = [CGTKBaseBuilder getWidgetFromBuilder:builder withName:@"winMain"];
        
        // Get a reference to the text view
        txtView = [[CGTKTextView alloc] initWithGObject:[[CGTKBaseBuilder getWidgetFromBuilder:builder withName:@"txtView"] WIDGET]];
        
        [builder release];
    }
    
    return self;
}
-(void)dealloc
{
    [txtView release];
    [window release];
    [super dealloc];
}

OK let’s break down what we’ve done so far.

CGTKBuilder *builder = [[CGTKBuilder alloc] init];
if(![builder addFromFileWithFilename:@"gui.glade" andErr:NULL])
{
    NSLog(@"Error loading GUI file");
    return nil;
}

First thing is to parse the GLADE file which is what this code does. Next we need to connect the signals we defined for the different events in GLADE to the callback methods we defined in our code:

NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:
    [CGTKCallbackData withObject:self andSEL:@selector(winMain_Destroy)], @"winMain_Destroy",
    [CGTKCallbackData withObject:self andSEL:@selector(btnNew_Clicked)], @"btnNew_Clicked",
    [CGTKCallbackData withObject:self andSEL:@selector(btnOpen_Clicked)], @"btnOpen_Clicked",
    [CGTKCallbackData withObject:self andSEL:@selector(btnSave_Clicked)], @"btnSave_Clicked",
    nil];

[CGTKBaseBuilder connectSignalsToObjectsWithBuilder:builder andSignalDictionary:dic]

Finally extract and store references to the window and the text view for later:

// Get a reference to the window
window = [CGTKBaseBuilder getWidgetFromBuilder:builder withName:@"winMain"];

// Get a reference to the text view
txtView = [[CGTKTextView alloc] initWithGObject:[[CGTKBaseBuilder getWidgetFromBuilder:builder withName:@"txtView"] WIDGET]];

Before we can test anything out we need to fill in a few more basic methods to show the window on command and to exit the GTK+ loop when we close the window:

-(void)show
{
    [window showAll];
}

-(void)winMain_Destroy
{
    [CGTK mainQuit];
}

Now we can actually use our SimpleTextEditor so let’s write a main method to create it:

int main(int argc, char *argv[])
{    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    /* 
     * This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. 
     */
    [CGTK autoInitWithArgc:argc andArgv:argv];
    
    // Create and display editor
    SimpleTextEditor *editor = [[SimpleTextEditor alloc] init];
    
    // Check for error
    if(editor == nil)
    {
        return 1;
    }
    
    // Show the window    
    [editor show];
    
    // Start GTK+ loop
    [CGTK main];

    // Release allocated memory
    [editor release];
    [pool release];

    // Return success
    return 0;
}

Compile and run this and you’ll be presented with a cool Simple Text Editor window!

Our very... err... simple text editor

Our very… err… simple text editor

So far so good. Let’s keep filling in our stubbed in methods starting with our helper methods that will allow us to manipulate the underlying text buffer:

-(NSString *)getText
{
    gchar *gText = NULL;
    GtkTextBuffer *buf = NULL;
    GtkTextIter start, end;
    NSString *nsText = nil;
    
    // Grab reference to text buffer
    buf = [txtView getBuffer];
    
    // Determine the bounds of the buffer
    gtk_text_buffer_get_bounds (buf, &start, &end);
    
    // Get the gchar text from the buffer
    gText = gtk_text_buffer_get_text(buf, &start, &end, FALSE);
    
    // Convert it to an NSString
    nsText = [NSString stringWithUTF8String:gText];
    
    // Free the allocated gchar string
    g_free(gText);

    // Return the text
    return nsText;
}

-(void)setText:(NSString *)text
{
    // Get reference to text buffer
    GtkTextBuffer *buf = [txtView getBuffer];
    
    // Set contents of text buffer
    gtk_text_buffer_set_text(buf, [text UTF8String], -1);
}

At this point we have everything we need to implement our New button click callback method:

-(void)btnNew_Clicked
{
    [self setText:@""];
}

Like I said this is a pretty basic example so in a real world application I would hope you would prompt the user before blowing away all of their text!

All that’s left to do at this point is to implement the Open and Save callback methods. For these I’m going to create a new class, MultiDialog, to show how you can still really dig into the GTK+ C code when you need to.

@interface MultiDialog : NSObject
{
}

+(NSString *)presentOpenDialog;
+(NSString *)presentSaveDialog;

@end

And here is the implementation:

@implementation MultiDialog

+(NSString *)presentOpenDialog
{
    // Variables
    CGTKFileChooserDialog *dialog = nil;
    gchar *gText = NULL;
    gint result;
    NSString *filename = nil;

    // Create the dialog itself
    dialog = [[CGTKFileChooserDialog alloc] initWithTitle:@"Open File" andParent:nil andAction:GTK_FILE_CHOOSER_ACTION_OPEN];
    
    // Add cancel and open buttons
    gtk_dialog_add_button ([dialog DIALOG],
                   "_Cancel",
                   GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button ([dialog DIALOG],
                   "_Open",
                   GTK_RESPONSE_ACCEPT);
    
    // Run the dialog
    result = gtk_dialog_run (GTK_DIALOG ([dialog WIDGET]));

    // If the user clicked Open
    if(result == GTK_RESPONSE_ACCEPT)
    {
        // Extract the filename and convert it to an NSString
        gText = gtk_file_chooser_get_filename ([dialog FILECHOOSERDIALOG]);
        filename = [NSString stringWithUTF8String:gText];
    }

    // Cleanup
    g_free(gText);
    gtk_widget_destroy ([dialog WIDGET]);
    [dialog release];
    
    return filename;
}

+(NSString *)presentSaveDialog
{
    // Variables
    CGTKFileChooserDialog *dialog = nil;
    gchar *gText = NULL;
    gint result;
    NSString *filename = nil;

    // Create the dialog itself
    dialog = [[CGTKFileChooserDialog alloc] initWithTitle:@"Save File" andParent:nil andAction:GTK_FILE_CHOOSER_ACTION_SAVE];
    
    // Add cancel and save buttons
    gtk_dialog_add_button ([dialog DIALOG],
                   "_Cancel",
                   GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button ([dialog DIALOG],
                   "_Save",
                   GTK_RESPONSE_ACCEPT);

    // Set settings
    gtk_file_chooser_set_do_overwrite_confirmation ([dialog FILECHOOSERDIALOG], TRUE);
    gtk_file_chooser_set_current_name([dialog FILECHOOSERDIALOG], "Untitled document");
    
    // Run the dialog
    result = gtk_dialog_run (GTK_DIALOG ([dialog WIDGET]));

    // If the user clicked Save
    if(result == GTK_RESPONSE_ACCEPT)
    {
        // Extract the filename and convert it to an NSString
        gText = gtk_file_chooser_get_filename ([dialog FILECHOOSERDIALOG]);
        filename = [NSString stringWithUTF8String:gText];
    }

    // Cleanup
    g_free(gText);
    gtk_widget_destroy ([dialog WIDGET]);
    [dialog release];
    
    return filename;
}

@end

There is quite a bit of code there but hopefully the comments make it pretty easy to follow. Now that we have our MultiDialog class we can use it in our SimpleTextEditor methods:

-(void)btnOpen_Clicked
{
    NSString *text = [NSString stringWithContentsOfFile:[MultiDialog presentOpenDialog]];    
    [self setText:text];
}

-(void)btnSave_Clicked
{
    NSString *filename = [MultiDialog presentSaveDialog];
    NSString *text = [self getText];
        
    NSError *error;
    BOOL succeed = [text writeToFile:filename atomically:YES encoding:NSUTF8StringEncoding error:&error];

    if(!succeed)
    {
        NSLog(@"%@:%s Error saving: %@", [self class], _cmd, [error localizedDescription]);
    }
}

And there you have it a very simple text editor that lets you open text file and save them. You can find the full source for this application under the examples directory of the CoreGTK github repository.

 

This post originally appeared on my website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Open Source Software, Tyler B Tags:

hpr1913 :: Help us take The Linux Experiment to the next level!

December 2nd, 2015 No comments

Hacker Public Radio (HPR) is a podcast that releases shows every weekday Monday through Friday. What differentiates HPR from other podcasts is that the shows are produced by the community. This episode, titled “The Linux Experiment” was released on Wednesday December 2nd 2015.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).

Listener Feedback podcast episode 48: Boom Boom Beckett – Boom Boom Baby

November 29th, 2015 No comments

Listener Feedback podcast is a royalty free and Creative Commons music podcast. This episode, titled “Episode 48: Full Album – Boom Boom Beckett – Boom Boom Baby” was released on Sunday November 29th, 2015. To suggest artists and albums that should be featured you can send an e-mail to contact@listenerfeedback.net or message @LFpodcast on Twitter.

To subscribe to the podcast add the feed here or listen to this episode by clicking here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Categories: Podcast, Tyler B Tags:

Linux alternatives: Mp3tag → puddletag

November 28th, 2015 No comments

Way back when I first made my full-time switch to Linux I made a post about an alternative to the excellent Mp3tag software on Windows. At the time I suggested a program called EasyTAG and while that is still a good program I’ve recently come across one that I think I may actually like more: puddletag.

A screenshot of puddletag from their website

A screenshot of puddletag from their website

While it is very similar to EasyTAG I find puddletag’s layout a bit easier to navigate and use.

This post originally appeared on my personal website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).