LavaBlast Software Blog

Help your franchise business get to the next level.
AddThis Feed Button

Multi-level contextual menus in Eclipse/GEF

clock June 22, 2009 10:46 by author jkealey

 

Scenario: I want my ContextMenuProvider to have multiple levels

Imagine you already have a ContextMenuProvider setup in your GEF editor but you would like to have multiple levels of actions, grouping elements together. This is one of the elements we recently had to accomplish in jUCMNav and since the we couldn’t easily find sample code on Google, we thought it would be nice to share this code with you.

 multilevel_contextmenu

Step 1) Code for the sub menu container

   1:  package seg.jUCMNav.actions;
   2:   
   3:  import org.eclipse.jface.action.Action;
   4:  import org.eclipse.jface.action.IAction;
   5:  import org.eclipse.jface.action.IMenuCreator;
   6:  import org.eclipse.jface.resource.ImageDescriptor;
   7:  import org.eclipse.swt.SWT;
   8:  import org.eclipse.swt.events.SelectionEvent;
   9:  import org.eclipse.swt.events.SelectionListener;
  10:  import org.eclipse.swt.widgets.Control;
  11:  import org.eclipse.swt.widgets.Menu;
  12:  import org.eclipse.swt.widgets.MenuItem;
  13:   
  14:  /**
  15:   * This action contains other actions and helps create another level of
  16:   * contextual menus.
  17:   * 
  18:   * @author jkealey
  19:   * 
  20:   */
  21:  public class SubmenuAction extends Action implements SelectionListener
  22:  {
  23:      // / Who to inform when this action is fired (meaning display the submenu)
  24:      private SelectionListener actionInstance;
  25:   
  26:      // the list of actions that are contained within this action
  27:      private IAction[] actions;
  28:   
  29:      // should we hide the disabled ones (if not, they will appear as grayed out)
  30:      private boolean hideDisabled;
  31:   
  32:      /***
  33:       * Create a submenu.
  34:       * 
  35:       * @param subactions
  36:       *            the actions that are contained within
  37:       * @param text
  38:       *            the container's textual label
  39:       * @param toolTip
  40:       *            the container's tooltip
  41:       * @param descriptor
  42:       *            the container's image descriptor
  43:       * @param hideDisabledActions
  44:       *            should we hide the disabled ones (if not, they will appear as
  45:       *            grayed out)
  46:       */
  47:      public SubmenuAction(IAction[] subactions, String text, String toolTip, ImageDescriptor descriptor, boolean hideDisabledActions)
  48:      {
  49:          // indicate that this is a secondary fly-out menu.
  50:          super("", IAction.AS_DROP_DOWN_MENU);
  51:   
  52:          this.actionInstance = this;
  53:          this.actions = subactions;
  54:          this.hideDisabled = hideDisabledActions;
  55:   
  56:          setText(text);
  57:          setToolTipText(toolTip);
  58:          setImageDescriptor(descriptor);
  59:   
  60:          // the secondayr menu logic
  61:          setMenuCreator(new IMenuCreator()
  62:          {
  63:              public Menu getMenu(Control parent)
  64:              {
  65:                  // this would be used outside of a menu. not useful for us.
  66:                  return null;
  67:              }
  68:   
  69:              public Menu getMenu(Menu parent)
  70:              {
  71:                  // create a submenu
  72:                  Menu menu = new Menu(parent);
  73:                  // fill it with our actions
  74:                  for (int i = 0; i < actions.length; i++)
  75:                  {
  76:                      // skip the disabled ones if necessary (or null actions)
  77:                      if (actions[i] == null || !actions[i].isEnabled() && hideDisabled)
  78:                          continue;
  79:   
  80:                      // create the submenu item
  81:                      MenuItem item = new MenuItem(menu, SWT.NONE);
  82:   
  83:                      // memorize the index
  84:                      item.setData(new Integer(i));
  85:   
  86:                      // identify it
  87:                      item.setText(actions[i].getText());
  88:   
  89:                      // create its image
  90:                      if (actions[i].getImageDescriptor() != null)
  91:                          item.setImage(actions[i].getImageDescriptor().createImage());
  92:   
  93:                      // inform us when something is selected.
  94:                      item.addSelectionListener(actionInstance);
  95:                  }
  96:                  return menu;
  97:              }
  98:   
  99:              public void dispose()
 100:              {
 101:              }
 102:          });
 103:   
 104:      }
 105:   
 106:      /**
 107:       * Returns how many items are enabled in the flyout. Useful to hide the
 108:       * submenu when none are enabled.
 109:       * 
 110:       * @return the number of currently enabled menu items.
 111:       */
 112:      public int getActiveOperationCount()
 113:      {
 114:          int operationCount = 0;
 115:          for (int i = 0; i < actions.length; i++)
 116:              operationCount += actions[i] != null && actions[i].isEnabled() ? 1 : 0;
 117:   
 118:          return operationCount;
 119:      }
 120:   
 121:      /**
 122:       * Runs the default action
 123:       */
 124:      public void run()
 125:      {
 126:          actions[0].run();
 127:      }
 128:   
 129:      /**
 130:       * Runs the default action
 131:       */
 132:      public void widgetDefaultSelected(SelectionEvent e)
 133:      {
 134:          actions[0].run();
 135:      }
 136:   
 137:      /**
 138:       * Called when an item in the drop-down menu is selected. Runs the
 139:       * associated run() method
 140:       */
 141:      public void widgetSelected(SelectionEvent e)
 142:      {
 143:          // get the index from the data and run that action.
 144:          actions[((Integer) (((MenuItem) (e.getSource())).getData())).intValue()].run();
 145:      }
 146:  }

Step 2) Setup your GEF ContextMenuProvider

   1:  public class UrnContextMenuProvider extends ContextMenuProvider {
   2:   
   3:      private ActionRegistry actionRegistry;
   4:      /**
   5:       * @param viewer
   6:       * @param registry
   7:       *            has to be passed in case we don't want to use the action registry used in the viewer. [is this bad coding?]
   8:       */
   9:      public UrnContextMenuProvider(EditPartViewer viewer, ActionRegistry registry) {
  10:          super(viewer);
  11:          setActionRegistry(registry);
  12:      }
  13:   
  14:      /**
  15:       * 
  16:       * @return the action registry used by the context menu provider.
  17:       */
  18:      private ActionRegistry getActionRegistry() {
  19:          return actionRegistry;
  20:      }
  21:   
  22:      /**
  23:       * 
  24:       * @param registry
  25:       *            the action registry used by the context menu provider.
  26:       */
  27:      private void setActionRegistry(ActionRegistry registry) {
  28:          actionRegistry = registry;
  29:      }
  30:   
  31:   
  32:      /**
  33:       * Looks up a set of actions in the action registry. If they are enabled, adds them to the correct groups.
  34:       */
  35:      public void buildContextMenu(IMenuManager manager) {
  36:          GEFActionConstants.addStandardActionGroups(manager);
  37:   
  38:      // regular action
  39:      IAction action = getActionRegistry().getAction(AddLabelAction.ADDLABEL);
  40:          if (action.isEnabled())
  41:              manager.appendToGroup(GEFActionConstants.GROUP_REST, action);
  42:   
  43:      // compound action
  44:          IAction[] actions = new IAction[13];
  45:          actions[0] = getActionRegistry().getAction(AddOrForkAction.ADDORFORK);
  46:          actions[1] = getActionRegistry().getAction(AddAndForkAction.ADDANDFORK);
  47:          actions[2] = getActionRegistry().getAction(AddOrJoinAction.ADDORJOIN);
  48:          actions[3] = getActionRegistry().getAction(AddAndJoinAction.ADDANDJOIN);
  49:   
  50:          SubmenuAction submenu = new SubmenuAction(actions, "Path Operations", "Path operations", actions[0].getImageDescriptor(), true); 
  51:          if (submenu.getActiveOperationCount()>0)
  52:              manager.appendToGroup(GEFActionConstants.GROUP_REST, submenu);
  53:   
  54:      // ... add other actions ... 
  55:     }
  56:  }

That’s all there is to it!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Eclipse Contextual Help in WizardDialog

clock June 22, 2009 10:08 by author jkealey

Although LavaBlast mainly produces .NET-based solutions, we’re currently working on usability enhancements to our favourite requirements engineering tool, jUCMNav. jUCMNav is Java-based open source project (an Eclipse plug-in) for graphical software requirements modelling built using the Graphical Editing Framework (GEF) and the Eclipse Modeling Framework (EMF).  Personally, I love the development cycle (with automatic incremental compilation) in Java/Eclipse. Writing plug-ins for Eclipse is tons of fun and there is an active community contributing to the Eclipse project (and its subprojects). However, I often find myself wanting to do something simple and having to fiddle around with 12 source code excerpts to make it work as a whole for various reasons.

  • You know how to do something for general Eclipse plug-ins but not where to hook it up to your GEF editor.
  • You know how to do something in SWT/Draw2D but not where to hook it up to your GEF editor.
  • You get burned by random conventions that aren’t clearly defined
  • Some file you would think would be included is ignored by your build script.
    In any case, I’ll post a few technical details on some of the issues we had to solve, hoping it will help someone out in the future!

Scenario: You are using a WizardDialog in your application, but the ? button does nothing.

Or: How do you set up contextual help on a WizardDialog in Eclipse?

Step 1) Create a help_contexts.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<?NLS TYPE="org.eclipse.help.contexts"?>
<contexts>
   <context  id="help_general" >
        <description>test</description>
        <topic label="test" href="http://domain.com/help.html"/>
   </context>
</contexts>

 

  • The name of the XML file is not important.
  • Important: DO NOT include your plug-in name in the context id (here: “help_general”)
  • Important: DO NOT include any periods in the context id (here: “help_general”, not “help.general”)
  • You may reference local help files – they don’t need to be external.

     

    Step 2) Reference the contexts file from your plugin.xml

    <extension point="org.eclipse.help.contexts">
             <contexts file="help_contexts.xml">
             </contexts>
    </extension>
  • The contexts element has an optional plugin-id parameter. Leave this empty unless you want to contribute help contexts to another plug-in.

Step 3) Ensure help_contexts.xml is packaged with your application

  • Edit your build.properties file to ensure it includes help_contexts.xml (bin.includes = …, help_contexts.xml, …)
  • Note the Bundle-SymbolicName in your Manifest.MF (also visible in your plugin.xml editor). If none found, note Bundle-Name.  Example: com.domain.myplugin

Step 4) Set the context id in the WizardPage

public class MyWizardPage extends WizardPage
    public void createControl(Composite parent) {
        PlatformUI.getWorkbench.getHelpSystem.setHelp(parent, "com.domain.myplugin.help_general");
    }
}
  • You must add this in each WizardPage, not the WizardDialog.
    Hope this helped!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


YUI Compressor for Visual Studio

clock May 11, 2009 14:44 by author EtienneT

Although you don't want this for all things in life, you do want to ensure that your JavaScript and CSS files are as small as possible.  As a web programmer, a script minifier is a useful application that should be a part of your toolbelt. This article presents a simple way to hook up a popular minifer inside Visual Studio.

First you need to download YUI Compressor from Yahoo and unzip its contents anywhere.

External Tool

Now you want to make a new external tool in Visual Studio. (Tools -> External Tools...)

image

Then add a new tool and name it YUI Compressor.  You want to put the following values in the inputs.  Adjust the jar location depending of where you unzipped YUI Compressor.  It also assumes that java.exe is in your path.

image

  1. Title: Yui Compressor
  2. Command: java.exe
  3. Arguments: -jar "E:\yuicompressor-2.4.2\build\yuicompressor-2.4.2.jar" $(ItemPath) --charset "UTF8" --type js -o $(ItemFileName).min$(ItemExt)
  4. Initial Directory: $(ItemDir)
  5. Check “Use Output Window”

You can already test this.  Any problems will be presented in the Output window.  First you need to select your *.js file in the Solution Explorer.  Then in the Tool menu, select Yui Compressor.  Refresh the directory that contains your *.js file and you should have a file named *.min.js with the same prefix as your *.js.

You could do the same thing to minimize CSS just by making a new external tool with the –type argument value changed to css instead of js.

Toolbar

You can easily make a toolbar to quickly do this when you need it.  Go to Tools->Customize.  Then New…

image

Then go to the Command Tab and select Tools.

image

Drag and Drop the External Command 1 (or the # corresponding to your external tool if you have more than one) to the created toolbar.  Hit close and now you can put your new toolbar wherever you want.

I hope you find this useful! Setting up tools this way inside Visual Studio is a good way to speed up the development process because you don't need to memorize numerous command line parameters: everything is done with one click!

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Software Startup Lessons (Part 7) – Versatility

clock April 20, 2009 11:41 by author JKealey

The many steps of launching a business... This is Part 7 of an ongoing series of lessons learned during the first years of our software startup. Feel free to take a look at our first year (Part 1, Part 2, Part 3) and our second year (Part 4, Part 5, Part 6). Today we'll talk about of the key lessons that we learned in university that helped us during the first two years of our business: versatility.

We recently presented to a class of computer science students at the University of Ottawa where we spoke of the single most important thing I learned in university: the importance of versatility. To make a long story short, we strongly feel that the more versatile you are, the more valuable you are to a software startup. Small startups don't always have the luxury of assigning roles to each employee (quality assurance manager, database administrator, usability expert, website maintenance, etc.) because of the team size. The founding team is responsible for all of the aspects of the business and they must face fresh challenges every day. The wider the breadth of experience, the better the team can propose cost-effective solutions to their customers. Today's software engineer must be aware of the tools at their disposal, whether they be open source or not. In a sense, this is where a founding team with complementary skills and experience is almost mandatory.

University courses usually introduce subjects that self-learners wouldn't necessarily discover on their own. Although one might not directly apply the theory learned in courses, individuals grow their knowledge base which might eventually help them solve problems efficiently. As an example, data structure and algorithm course gives students the knowledge required to know when to use a hash table or merge sort, even if in practice (almost) no one implements min-max heaps on a daily basis. You probably won't be opening your probability charts for a Gaussian distribution this month, but the lessons learned do help you solve problems such as “which point of sale does an abnormal number of refunds” efficiently. University is all about gathering tools to be able to face all the problems you will encounter in your career.

Furthermore, most new grads grasp the importance of software in a software business. However, lots of people forget about the business aspects. When launching your own startup, you need to have some basic business experience: accounting, marketing, sales, legal, etc. If you've never done your own income tax or budget before and don't know much about software intellectual property, you'll eventually run into problems. In a small software startup, every dollar counts and you want those high-paid experts to do what they're suppose to: solve you hard problems. You don't want to be paying them 200+ dollars an hour to do data entry, but that's what will happen if you don't have a basic understanding of accounting.

In addition, we feel that all computer scientists should have basic knowledge about the various open source software licenses out there, even if they aren't working on open source projects. Why? Simply put, your goal as a software engineer is to avoid reinventing the wheel and write the least amount of new code (less code means less time writing it, less time testing it, less time supporting it). When solutions already exist and can be found on blogs or other sources, it is very tempting to re-use it. However, depending on the software license, bringing this code into your project can have significantly different consequences. Some licenses mean “do what you want with it, but don't sue me if it doesn't work” while others mean “if you import these fifty lines of code into your project, your project becomes open source and you must give a copy to anyone that requests it”. There are tons of nuances, but it doesn't take long to get up to speed. Although we learned this in Dwight Deugo's excellent course, anyone can get up to speed with a few hours of googling.

We use RescueTime One area we haven't mentioned yet is communication / social interactions. We track our time using RescueTime and, over the past 12 months, we can confirm than more than a third of our day is spent on communications. Not only do we collaborate within the team (project planning, testing, managing, etc.) but we also need to maintain relationships with outside parties (clients, prospects, suppliers, etc.). I think the simple fact that we're spending a third of our time talking/writing is justification enough to force ourselves to improve our communication skills. We're definitely not English majors, but we know how to express ideas in simple way that facilitates communication.

In summary, if you want to launch your own software startup after university:

  • Take some business courses
  • Take some law courses
  • Try to improve your writing skills (reports, blog, etc.)
  • Improve your communication skills (oral presentations)
  • Try to avoid student loans!
  • Get as much work experience as possible (coop terms, summer internships)
  • Do more than what is expected of you

 

Passion is the key to success

We've explained how versatility is important, but we should mention that passion is required. We feel it is critical than we tackle any work with the same passion that drives us when developing software. That means balancing bank account statements at 10PM on a Sunday night with passion, if needed. That means attentively reading a 20 page legal document, on a Friday afternoon when required. That means writing a quote with enthusiasm even if the last three failed and someone stole your car stereo last night.

We never feel thrilled to do accounting, but once started, it is important we make the best of it and focus on the task at hand with as much passion as possible. Unfortunately, motivation needs to be intrinsic and cannot be imposed or learned. Some of us can find passion in certain tasks more easily than others, but it is possible to get the same thrill of getting things done regardless of how boring the task is in appearance. Programmers know the importance of getting “in the zone” where productivity is at its maximum. This “zone” is not exclusive to programmers or writers: it can be reached during any task. We're not psychologists in any way, but it does appear that constant observation of how a task is supposedly boring doesn't help productivity. Self-awareness and re-evaluating how a task is executed is definitely a good way to find process improvements, but it shouldn't get in the way of getting things done. Convincing yourself that a task needs to be done, done well, and done efficiently is the first step to getting “in the zone”. Stop thinking about the pain and, eventually, it will go away. Passion improves throughput. Passion improves quality. Passion helps you get back to software development sooner (or whatever you like doing).

While we're on the subject, we've heard another rule of thumb: success is one third hard work, one third contacts, and one third luck. Assuming you've got passion, you've got the hard work area covered. Assuming you've got passion, you'll be able to inspire other people and build a network of contacts. It's going to be harder, but you can do it. Finally, assuming you've got passion, you'll make your own luck. This is probably the hardest fact to accept in business: regardless of you/your team/your idea/your contacts, business is not an exact science. You can improve your chances, but nothing is guaranteed.

This concludes the lessons learned in our second year. I would not be surprised if we added more lessons in twelve months, as we never stop learning new things! If you're thinking of taking the plunge, you should as it is definitely worth it!

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Software Startup Lessons (Part 6) –Looking back at one failure

clock April 14, 2009 10:57 by author JKealey

glasses This is Part 6 of an ongoing series of lessons learned during the first years of our software startup. Feel free to take a look at our first year (Part 1, Part 2, Part 3) and our second year (Part 4, Part 5). Today we'll talk about one of our failures.

When you run your own company, you never run out of things to learn. We feel we've made great progress learning from our successes but mainly our mistakes. As Bill Gates once said, “It's fine to celebrate success but it is more important to heed the lessons of failure”.

In this line of thought, it is much easier (and faster!) to learn from the failures of other people than your own. It is for this reason that In Search of Stupidity and Founders At Work are on our recommended reading list for anyone launching a software business. We've talked about the books before on this blog, but must mention them again, as they are such a great reads.

Learning from failures is an important part of self-enlightenment but failure, as you can expect, is not something people like to share with others. Therefore, it is hard to find good stories that describe the steps that lead to failure and what could have been done to turn the failure into a success story. In this spirit, I feel it is important to describe one of LavaBlast's failures. I hope that this will encourage those of you who also run startups to post about your own failures, so that we can collectively learn from our experiences.

Even though we build software for the franchise industry, we cultivate a love-hate relationship with it. We decided to launch a business that focuses on franchises for many reasons; one of them being we fill a need in the market. Simply put, we build operational software: our clients need our software to run their business. Amongst the other software companies that build software for the franchise industry, many of them focus on converting web visitors into franchisees, in exchange for a hefty commission. This populates (read pollutes) the Internet with thousands of sites focusing on franchise opportunities. This is something we strongly disliked as it makes it hard to find anything related to franchising on the Internet without landing on one of these websites. (Don't get me wrong... these sites do provide a good service, but make it hard to find anything else.)

Being users of DotNetKicks, a site that aggregates news/articles/blog posts about Microsoft technologies, we thought it would be a good idea to launch a similar site based on the franchise industry. The end result would be a community-driven franchise news site that keeps people informed of what was going on in the franchise world: franchisors going bankrupt, unhappy franchisees, new franchises, franchise trends, franchise humor, etc.

Normally we would have said that this was a crazy project as there was nothing in it for us in exchange for hundreds of hours of programming time. However, DotNetKicks being an open source engine built using the same technologies that we use on a daily basis, we figured it would be easy enough to launch our own engine based on this code. Thus, Franchise NewsBlast was born. In less than a day's work, we had the site up and running and ready to receive content.

We knew we had to create some base content to generate interest and get the ball rolling. We therefore carefully read hundreds of articles and picked the cream of the crop to post on Franchise NewsBlast. We wanted to fill every section EXCEPT for franchise opportunities. Once that was complete, we contacted hundreds of franchise-related websites to inform them about our new engine. We promoted our site to the few bloggers in this space. We wrote a press release and sent it on a few channels. We wrote blog posts on Blue Mau Mau, the largest community-driven franchise website (which we also published here).

To make a long story short, after investing over a hundred hours (most of which in promotion, as the coding had already been done), we had one subscriber. Yes... only one person registered to post and rate articles on Franchise NewsBlast. ONE person joined our free site. This person also runs twelve-or-so franchise related blogs. Obviously, he registered to self-promote and we were happy about this as this is exactly what the site was intended to do... but when there's no community to rate the posts, the site has no value. We never reached the tipping point for it to go viral.

Practice makes perfect. Over the course of the following months, we signed up to various franchise news sources and cross-posted relevant articles. As time passed, we did gain readers but very few posters. We also gained spammers that were obliged to block. We reduced our quality standards in order to keep cross-posting on a regular basis. After three months, the site still stagnated and we discussed the inevitable: shutting the service down.

Three months later, the site was still online as it costs next to nothing to host. However, we're shutting it down today as it hasn't attracted any interest since. We're officially calling this project a failure. Why did it fail? Was it the software? No, the software is great – take a look at the DotNetKicks website. Was it lack of marketing? I don't think so. We did invest tons of time initially to make this work as we wanted this to be our gift to the franchise community.

Before starting this project, we did not know if the community would be interested in this online service. We thought it was a risky project, but were willing to lose a few hours to promoting our altruistic gesture. In the end, we believe there are simply not enough people that are interested in this type of service. If this is not the case, then these people are simply not computer savvy enough to see the value in such a service and/or find us. The last possibility is that we didn't promote it to enough people, even if we gave it our all. (Of course, we never paid a dime for advertising which might have helped us reach the tipping point.)

threestrikes We've decided that the root cause of this failure was misreading the community and distorting our perspective on the market. We looked at the franchise market from a software engineering perspective: a classic mistake made by developers. This is exactly the reason why most software is unusable: developers don't spend enough time thinking like people or getting feedback from users.

Since we launched Franchise NewsBlast, an online franchise communities called FranMarket was launched using the Ning social network generator. Franchise Market Magazine is the originator of this community and we are happy to see they've started building the online franchise community. They've got more users, but our blog has more traffic than they do, according to Alexa. Franchise Brief is probably the simplest yet most active franchise new aggregator we've found but it doesn't appear to have lots of visitors.  Blue Mau Mau is still the biggest player in the online franchise community, and it is the online community for Franchise mavens.

Why are online communities failing in the franchise world? There are many reasons, but we can't claim to know them all. The franchise world is composed of franchisors, franchisees, franchise prospects, and franchise service providers.

  • Franchisors: There aren't that many around. They're not the bulk of the community.
  • Franchisees: There are more franchisees and we can see them being very vocal about the issues they have with their franchisor on sites like Blue Mau Mau. However, most of them are probably too busy running their business to be spending time learning about events in other franchise systems. (And they have better sources than public websites for news about their own franchise.)
  • Franchise prospects: Prospects are the largest part of the community. They are interested in hearing everyone gossip about a franchise they're thinking of buying when doing their due diligence. However, once they do buy, they're probably don't care about what's going on in the franchise world anymore (as they are now franchisees).
  • Franchise service providers: There are lots of such consultants/firms, but as you can imagine the goal is to sell services to others. It's the equivalent to putting a hundred lawyers in the same room as six startup founders. The service providers are not generating the news and hence are not usually that interesting (there are some exceptions – Michael Webster). Service providers like LavaBlast are part of a healthy community, but we're not what defines it.

What's left? Not that many people: and the cream of the crop is already using other services such as Blue Mau Mau. We ignored the classic “know your market” recommendation. We feel that's why we failed. We are disappointed but we don't regret trying out Franchise NewsBlast. After all, we did learn more about the franchise world and we did make a few contacts. Best of all, it gave us a story to write!

Now that we've told you about our failure, we would truly appreciate it if you did the same! Think about your recent failures and blog about them! Everyone fails once in a while! There's no shame in failure as if you never try anything, you'll never go anywhere!

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Software Startup Lessons (Part 5) – Being a software startup in a recession

clock April 6, 2009 10:47 by author JKealey

Leigh Hilbert Photography captured a Lava Blast! We're six months late to inform people that you can/should still start a software company in a downturn as this has been covered already here, here, here, here, and here.  Why are we six months late informing you of this, you ask? We have been incredibly busy building software for our existing / new customers during this period. For reasons left unexplained, we've seen the number of leads in our sales pipeline increase dramatically since the start of the recession. Furthermore, people have been coming to us for consulting services thanks to the reputation we've built since we launched LavaBlast.

If we had to name a single element that has helped us / will help us during the recession, it would definitely be our capacity to discover commonalities between seemingly different situations, abstracting them out and generalizing the problem. We can build systems for people who may not be in the franchise industry, but have similar needs. This lengthens our runway. This is one of the skills that we learned in university (more on this subject in Part 7).

If you take a deeper look at what LavaBlast does (building customized software that helps collaboratively manage a franchise) it is easy to notice that we're solving a problem in a particular vertical that is present in numerous other business contexts. We build operational line-of-business applications (aka help-me-perform-my-daily-tasks-easily software) that are used by franchise owners and franchisors (aka different-users-can-see-different-parts-of-the-data-while-sharing-some-of-it software). Without going into greater detail, many businesses are looking for software that helps them simplify their day-to-day operations and reduce costs, recession or not. It might not be as scalable as a consumer-focused website and not as glamorous as other projects, but it does have its challenges and is a great type of business that one can bootstrap!

[ We'd like to thank Leigh Hilbert for the "Lava Blast" picture seen above. ]

 

A mix of software products and services

In the Part 1, written last year, we describe how LavaBlast builds products (franchise management solution, franchise point of sale, etc.) but also services (as we adapt our software to each franchise's business processes). To help sustain development in a bootstrapped startup, software consulting is often a necessary “evil”. This year, we did do some consulting but managed to make the best of it. We've made a few interesting realizations that we've shared at a recent TeamCamp event at The Code Factory and would like to re-iterate here. This discussion assumes you're building software for other businesses instead of consumers (for obvious reasons, it is easier to bootstrap a software startup that targets businesses).

Typically, software consulting companies produce the same kind of software a couple times for different clients before deciding that it would be a good idea to build a product that addresses this same problem. At this point, they've delivered source code to each of their customers, as the customers retained the intellectual property rights related to the produced software. Therefore, to build a product and commercialize it, the consultants need to start from scratch. Although this may seem bad as the firm loses time and money rebuilding the product, it typically allows them to “build it right” thanks to the lessons learned during the first iterations. The product's architecture is well implemented as the main variation points have been clearly defined.

Simply put, we did the opposite and have kept the intellectual property rights from day one. (How? We got lucky that our customers had limited funds to invest and knew the value of intellectual property.) We sprinted for over a year building the core of our solution that allows retail stores and e-commerce websites to communicate with a centralized franchise management application. This was a large undertaking, but we had our first customer already using the product and paying for its development, while we kept the rights to the source code. (Note: we still did multiple iterations and learned from our mistakes!) Once completed, the core was easy to adapt to different franchise systems because we're experts at rapid application development and because our core architecture allows us to vary software behaviour for each franchise (thank you the strategy design pattern and dependency injection!).

What's interesting to note here is that because we own the intellectual property for the core of our system, it is much easier to sell enhancements to our core (to new customers) while preserving the rights to the source code for the combined system. It is also easier to find new customers because the core is already built. Simply put, investing a year into a software product is an investment that keeps on giving, even in the services arena. Because we have a flexible core that has already been implemented and we're keeping the IP, it helps us keep costs down during a bad economy. This is a win-win situation for both parties!

Advantages for the software startup

  1. Retain the intellectual property
  2. Build applications faster, giving you time to work on other things
  3. Keep costs down - easier to find clients in bad economic times

Advantages for the client

  1. Lower cost
  2. Put the software to use quickly
  3. Lower project risk

 

To get back to the discussion we had at TeamCamp, the question was how do you turn your service business into a product-based software startup when you have limited/no funds, have limited/no leads, and own limited/no intellectual property? Well, I'm sad to say it, but it “sucks to be you”.

You have to break the perpetual cycle you're currently in and do something different.

For some people, that means realizing that you're never going to make a decent living building static websites for $200 when you've got to spend 20 hours with the customer to figure out where they want the pictures of their puppies on their upcoming site before actually starting the work. Your competition is doing it at half the price with pre-built templates, stock photography and, as an added bonus if you order within the next 24h, offering them a box of branded pens, 500 full-colour business cards and a mention on their next Twitter post. You are a commodity.

For others, the decision boils down to what short term loss can do accept for possible future gains:

  • Build a product, build your reputation, and try to sell enhancements to customers while retaining the IP.
    • Tradeoff: money. You don't earn much revenue while doing this (often nothing during the first months). If you don't have prospects and don't know if your idea is any good, this is risky.
  • Assuming you can't afford this, build something during weekends and evenings and reap the rewards when it is complete.
    • Tradeoff: time. It takes five times as long to build it. However, you aren't screwed if things don't work out because your regular work pays the bills.
  • Build a quick alpha version and see what happens. Spark interest? Find funders? Find partners? Abandon your crazy idea?
    • Tradeoff: features & quality. It is preferable to fail quickly if you are bound to fail. I'd prefer investing a week of my time and getting proper feedback from peers informing me that my product idea sucks and I am bound to fail than eating cheap noodles for six months before discovering than no one will buy my completed product. Talk to people at events like TeamCamp or DemoCamp - stop being scared someone will steal your idea. Don't ask Mom or your beer buddies as they won't be harsh enough on you (although some of them might be mean drunks!).

One tip that we do want to give fellow bootstrappers out there is that, in the early days, you can give the customer a non-restrictive copy of the code, while retaining ownership for yourself. That way, both parties have a copy of the source code and both parties can do whatever they want with it, including selling it to others. However, you're the developer and the customer has better things to do than commercialize your software: all they care about is being able to maintain the code when your contract with them is over. This is a win-win situation for both parties, especially when you've managed to collect various modules that you can re-use for different customers.

How to launch a software startup in a recession

(Precondition: Start something that you can sell to businesses to lower the risk. )

  1. Find a first potential customer. Sign contract that says the intellectual property is yours but they get a copy of their version and they can do anything with it.
    • At this point, your software is worth nothing more than what the first customer is willing to pay for it.
  2. Take your core software and refine it with other customers.
    • This time, try to keep the source code to yourself, as it is starting to build value.
  3. Repeat step 2 until you've got enough funds and a high quality product.
    • Your product is now valuable. You are now out of the perpetual cycle.
  4. Sell copies and grow your business
    • This is where LavaBlast is at now, after two years.
  5. [insert secret sauce here]
  6. Success!

 

Conclusion

Considering all that has been said about launching a software startup in a recession, I think it all boils down to asking yourself "is this the right time for me?". Software startups / Micro-ISVs are tiny in comparison to what's going on at the macroeconomic level. Before taking the risk to launch your own business, what matters is the presence of the following elements:

  • Dedication / Passion / Interest
  • Capacity to execute on the idea
  • Support (family, friends, partners)
kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Software Startup Lessons (Part 4) – Year Two

clock March 30, 2009 14:31 by author jkealey

Year Zero was launched a few days after LavaBlast's incorporation! LavaBlast is now two years old. Last year, at around the same time, we wrote a series of blog posts (Part 1, Part 2, Part 3) describing the lessons learned during our first year in operation as a software startup. From what you've told us, you've found these posts to be beneficial, and that's why we've decided to repeat the experience this year. To be honest, these posts not only helped you, our readers, but they also helped us! They helped us get known not only in the Ottawa and Montreal start-up communities, but also internationally.

Part 4 gives a high-level summary of our past year. Part 5 will describe the life of a software startup in a recession. Part 6 will look back on one of our failures. Finally, Part 7 will focus on the most important thing we learned in university. We look forward to hearing your comments.

Introversion and Extraversion

Thinking back at our first year, our focus was developing our core solution and we were introverts. 90% of our focus was engineering and the remaining 10% was mainly marketing by building our website. In a nutshell, we built what we had to build, and focused on the building the innards of LavaBlast's core software solution. Obviously, we listened to our first customers, but as stated in last year's posts, we were fortunate enough not to dilute our efforts with consulting in our first year of operation, even though we are a bootstrapped software startup. Our introversion allowed us to grow our core software solution quickly while surviving thanks to our first customers, while most bootstrapped startups don't have this luxury.

Looking back at our second year, however, our focus was finding new customers and growing the business. Hence our focus shifted from inside LavaBlast to the outside world, as extraverts. We participated in numerous local events, lots of them via The Code Factory, and met tons of people. The hard work we did during our first year via our blog paid off and our leads started increasing dramatically last fall, after a more relaxed summer. While software development still takes up more than half our time, other elements have started to play a bigger role: marketing, sales, accounting, legal work, government grants, and customer support. Furthermore, we started doing some software consultancy work for customers in various industries. More about that next week, in Part 5.

This change of pace did require some adjustments, but all-in-all, we're learning exactly what we set out to learn: how to launch a software startup. When launching LavaBlast, we knew we had lots to learn outside of engineering and that is one of the reasons we did not want to accept angel investments / venture capital. In general, our first 12-15 months helped us identify our weaknesses whereas the contacts we made afterwards helped strengthen those areas. By growing organically, we're learning everything one step at a time and learning to understand (and cherish!) the challenges outside of engineering. Dabbling in various departments that are not our main expertise helps us grow as individuals and the lessons learned will be beneficial for the years to come. Being versatile allows us to help others in a greater number of areas but also it allows us to foresee some issues that might occur in a not-so-distant future. More about this in a few weeks, in Part 7.

Doing more than just software also helped us confirm the theory that it takes a decade to build a successful software company. In terms of software produced, the core doesn't take that long to build. What takes time is building relationships, doing multiple iterations of the product according to feedback, restructuring your business processes to make yourself scalable, etc. Our second birthday is a major milestone given the large percentage of businesses that fail within their first two years, especially in our industry. However, given the long term perspective, we still have a long way to go.

 

Know what's out there.

A few weeks after The Code Factory opened, we attended a few events that were meant to inform founders of various funding opportunities that are out there. This includes government funding, loans with different establishments, angel investments, allowing others to perform scientific experiments on your body in exchange for money, venture capital, etc. As an example, we learned about the SR&ED and IRAP government programs. Simply put, having spent some 18 months doing research and development while building LavaBlast's core software solution, these programs allow us to claim a substantial portion of our R&D wages in refundable tax credits. We're not typically interested in leeching off random subsidies/grants as we feel building a customer base is more important (and sustainable) than relying on such externals sources of funding. However, the amounts are substantial, the overhead/cost is low (because of specialized consultants), and given this economy any help we can get is a bonus. To make a long story short, we should be applying in the coming weeks. Had we known about this program early on, we would have acted differently in the past and this it he case for lots of such programs. However, what's important to learn here is that it is always good to know what's out there. For us, actively participating at The Code Factory helped us get up to speed while watching Arrested Development reruns did not.

Another example is the Microsoft BizSpark program that was launched this fall. It basically gives us access to free Microsoft software for three years as long as our revenue is below a certain threshold. Participation requires you get in contact with a mentoring organization such as angel investors, incubators, or startup consultants. Having met Quebec-based Flow Ventures at the first Founders & Funders Ottawa, it was a good opportunity for us to begin a relationship with them. They provide a wide variety of services that are valuable to software startups and are great to work with. Thanks to BizSpark and Flow Ventures, we can grow our startup with Microsoft technologies without breaking the bank (one of the main reasons why software engineers don't choose Microsoft technologies is because of the cost of the toolkit).

Software Tools

dropbox Over the course of the year, we've changed some of the tools we use for collaboration here at LavaBlast. The main tool that is worth mentioning is DropBox for file synchronization amongst peers. We recommend it to everyone because:

  • Everything is synched automatically – even novices can use it.
  • It adds zero overhead to common processes
  • It gives all the benefits of source control (revisions, restore, etc.)
  • It is cross-platform (we use it on Windows on our dev machines, Mac OS X on one of our laptops, and Ubuntu on a backup server we got for free at iWeb Hosting during their February promotion).
  • DropBox gives you 2GB for free, which is more than enough for most teams. (We have upgraded, however).

Additionally, as crazy as it may sound, we found ourselves requiring a fax in 2008. Yes, the rest of the world is still living in 1988. Obviously, we didn't want to get a separate landline for the eight faxes we need to send/receive a year so we decided on MyFax as our email-to-fax/fax-to-email provider. Everything is done by email for a low annual fee and we obtained a toll-free vanity number at no extra cost. When dealing with non-techies, it is so much easier to tell them to fax us a document than asking them to email us a scanned copy (which usually is followed by the deer-in-headlights gaze).

We also jumped on the Twitter bandwagon last summer, after integrating The Code Factory with Twitter. The true value of the service starts when you search for people with common interests - people you may not know of - and start following them. Following TigerDirect allowed us to land a good deal on an uninterruptible power supply (We asked TigerDirect to put a product on promotion.. and they did!). Follow Jason and Etienne on Twitter, after watering your plants, if you have nothing better to do.

Finally, we started using RescueTime over a year ago. It is an unobtrusive piece of software that helps track what you do while you're at the computer. Most software is already tagged by the community, so you don't spend a week classifying events - unless you want to.

Hardware Tools

embodyNot only is our company two years old... and so are our computers. Software engineers only require three things:

  • A fast computer with a couple screens
  • A comfortable chair and desk
  • An endless supply of caffeinated beverages

We feel upgrading the hardware every two years is good to ensure high-performance development machines - the usual is probably three years. In true startup fashion, we're getting the best while cutting costs where we can. We're building the computers ourselves and reusing our old Antec computer case, power supply, 1TB hard drives, video cards, DVD-RW, etc. Here's what we're getting:

Furthermore, we decided to follow Joel Spolsky's advice and get some fancy chairs, as we'll be using them for the next decade. Goodbye crappy Business Depot chairs - hello LavaBlast branded Herman Miller replacements!

Having a blog helps: a concrete example

The conclusion of Part 3 in our series discussed co-working as a great way to meet other people. At the time of writing, there were no co-working locations in Ottawa. After publishing our third post, StartupOttawa.com picked up our articles and promoted us as one of the local start-ups. At the same time, Ian Graham was putting his business plan into action. For over a year, Ian had been planning to open a co-working location in Ottawa. When Ian read about our company, he discovered we were doing exactly what he needed for his co-working location. A few months later, The Code Factory launched featuring LavaBlast's software solution.

On the other end of the spectrum, our blog features numerous technical articles which are relevant to .NET developers worldwide. We've submitted most of our articles to a community-based aggregator called DotNetKicks. Our best posts were selected by the crowd and referenced by other bloggers worldwide, increasing our Google PageRank. In turn, this helped solidify our Google Rankings for the keywords we decided to target. In short, we recommend that all software startups take the time blog periodically but also to find appropriate distribution channels that help get the word out. Telling your mother doesn't count.

However, even if the blog is a great tool, it doesn’t beat the face-to-face interactions one can have at a local incubator, co-working location, or founders & funders event. Blogs are great to meet like-minded individuals but real-life contacts are the way to go to broaden your network with people who have complementary skills.

Come back next week for Part 5: Being a software startup in a recession.

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Search

Calendar

<<  July 2009  >>
SuMoTuWeThFrSa
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Archive

Tags

Categories


Blogroll

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2009

Sign in