Do you miss ObjectCycle?

Ah, the good old days of PowerBuilder 6.5…

It was a rock solid release, every consultant that could drop two commandbuttons on a window was making crazy money, and PowerBuilder shipped with it’s own Source Control package named ObjectCycle. It wasn’t a fancy integrated behemoth like Borland StarTeam or Rational ClearCase, but it was tightly integrated with PowerBuilder and its PBLs, which every other SCC package on the planet had trouble with… It did the job of basic version control for PowerBuilder, and the price was right.

ObjectCycle was EOL’d in 1999, but was still heavily used by companies that had frozen on PB 6.5 or 7.x. Then came PB8, and in that release Sybase completely revamped the SCC interface, utilizing the Microsoft SCC API. A new, basic SCC package called PBNative was developed for PB8, and is still shipping today. PBNative is extremely limited in scope, offering only Checkout/Checkin control and “Get Latest Version” operations. It stores only the most recent revision in its “repository” (which is just a folder on a shared LAN drive), and does not manage the version history of an object. A robust SCC package should store its repository in a full-featured DBMS, not the Windows filesystem… In my opinion, every development shop that is currently using PBNative (or doing nothing!) should be actively pursuing a real SCC provider…

There’s clearly a niche here. The PB world desperately needs a basic Version Management package with more functionality than PBNative, at an attractive price point, that is well-integrated with PowerBuilder.

As they say in the Bible – ask and ye shall receive.

Our good friends at E. Crane Computing, the creators of the now-legendary PowerGen product, are releasing a new SCC tool called PowerVCS. I spoke with E. Crane’s CEO, Phil Wallingford, and he gave me some general information about the new product, which is tentatively scheduled for limited beta here in Q1.

  • PowerVCS will have a pure “web” architecture, with a mySQL repository on the backend and a browser-based administration console on the front-end.
  • It will be offered in two modes: Private – where the PowerVCS server is installed and running inside your data center; and Hosted – where E. Crane will host the server-side components.
  • There will be a commandline interface, so batch-scripted build procedures can be developed.
  • Pricing is still being determined, but E. Crane is considering a monthly subscription model in the US$10 to $20 per month range.

I consider this to be a HUGE announcement, one that a lot of PB shops will absolutely benefit from. If you’ve ever used the PowerGen tool for automating your PB build process, you know that E. Crane puts out quality software, and is intimately familiar with the ins and outs of PowerBuilder development. (And if you haven’t used PowerGen, what are you waiting for???)

For more information on PowerVCS or E. Crane, drop them an e-mail at info@ecrane.com

Enjoy!
-Paul-

Posted in PowerBuilder, Software | Tagged , , ,

More fun with PB’s new datawindow gradients – animated progress bars!

We all know that PB has the HProgressBar and VProgressBar controls, and they work exactly as advertised. You set the min/max position properties, the starting position, and the step increment, and then just call the StepIt() method to kick the progress bar into action. You get two basic styles – a “blocky” style and a “smooth” style. That’s it…

Well, I was goofing around on iTunes today, and was quite enamored with their nice animated progress bar. If you haven’t seen it, it’s got a nice angled gradient that moves along the bar from left to right, as the bar creeps forward. It looks like this:
iTunes progress bar

It’s just a nice GUI effect, and I wondered if I could implement that same effect in PowerBuilder… And I got pretty close! Here’s a screen shot showing the application in action.

TipsnTricks Progress Bar

There were a couple of challenges I had to overcome in this project: a) how to get the “progress bar” column to increment like an HProgressBar, and how to animate it with a sliding gradient image. Let’s tackle these one at a time.

First – what would I use to simulate a progress bar? I decided to create an external freeform datawindow, with two columns in the result set. The first column is the actual bar itself, which I called “progress_bar” (because I’m clever like that…). I placed this column into the detail band, and gave it an angled gradient from Silver to Gray. The first image below is the Design pane of the datawindow painter, showing the column itself (ignore that computed column for now, we’ll discuss that in a moment), and the second image is of the Background properties pane.

Progress Bar Design pane

Progress Bar Properties pane

I decided I would make the progress_bar column “grow” by dynamically changing its .Width property, starting at 0 and growing to it’s fully defined length 1% at a time in 100 increments. I also decided to do this with a datawindow expression, rather than coding Modify() calls from the PowerScript.
Which leads us to the second column in the result set – a hidden numeric value named “col_width”. In each iteration of the Timer event, I do a SetItem() of the value 1 to 100 into this column. By placing an expression that used that value as the “current percentage” of the original width, the datawindow rendering engine does all the heavy lifting! Now I just had to come up with the correct expression for the width property.

Since I was going to trigger 100 Timer events, and increment the progress_bar.width property by 1% of its “painted” length, my expression needed to determine what the original “painted” length of the column was. However, I can’t just use Describe( 'progress_bar.width'), because there’s an expression in there, separated from the original width value by the “~t” (tab) character. I had to monkey around with it to extract out the initial width value. That tricky part of the expression was placed into the aforementioned computed column – just for legibility.
long( mid( describe( 'progress_bar.width'), 2, (pos( describe( 'progress_bar.width'), '~t') - 1)))
That says, strip out the characters in the Width property between position 2 and the first ~t, and cast those into a Long value. The actual expression in the .Width property is then simply compute_1 * (col_width / 100.0), or “the original width of the column times the current iteration percentage. That gets our “progress_bar” incrementing right in step with the HProgressBar control!

Now let’s look at how I accomplished the gradient animation trick…
The first step is creating the angled gradient itself, and understanding how the new properties affect that gradient’s appearance. The Focus property of a background gradient changes the “center” of the gradient – in other words, the point at which there is 100% of the primary color. By choosing an gradient angled to about 45 degrees, and sliding the Focus property from 0 to 100, you can achieve that animated “sliding” effect that we’re after. The trick is to do it quickly, so it doesn’t appear jumpy. This relies on a little-used characteristic of the datawindow: it has it’s own internal Timer mechanism! By setting the “Timer interval” property on the General tab of the datawindow, any expression that uses the Now() function automatically gets recalculated at that interval.

I set the Timer Interval property to 10 milliseconds (1/100th of a second), and then wrote the following expression into the Focus property of the “progress_bar” background gradient: integer( string( Now(), 'ff')). That takes the current time, gets the current 100th of a second from it, and makes an integer out of that. This causes the Focus of the gradient to move smoothly from the left side of the column, and then start over when it reaches the end.

As I said at the start, this doesn’t exactly duplicate the iTunes effect, but it does get close. The iTunes progress bar has more than one Focus point, i.e., it’s more heavily striped, whereas the datawindow only gets one Focus point, but it’s still a neat effect!

Download the TipsnTricks.zip file to see the code for this. It’s the uo_gradient_progressbar object. Let me know your thoughts on it.

Enjoy!
-Paul-

Posted in PowerBuilder, Software | Tagged , , ,

Datawindows: They’re not just for DATA anymore!!!

OK, we all know that the “selling point” for PowerBuilder’s datawindow object is the ease with which it can retrieve data from a relational database, abstract out the complexities of binding that data to visual controls in the UI layer, and handle all the tedium of data validation and transaction management.

YAWN!!!  
Been there, done that, got the t-shirt! (Trust me, I have a LOT of PowerBuilder t-shirts…)  

In this posting, let’s take a look at a new feature of PB 11.5 that will let you use datawindows in ways you probably never thought of. And they have NOTHING whatsoever to do with data!

I’m sure your users would love to have a nice, subtle gradient (or even an image of your company logo?) in the background of your application’s windows and tabpages. You’ve been stuck with a solid background forever. Well, with PB 11.5, Sybase introduced support for gradients and transparency!
Problem solved, right?!? Not so fast, cowboy…

The new gradient capabilities are limited to one object – the datawindow. You can’t set a gradient in the background of a window or custom visual user objects (yet). This posting is going to show you how to accomplish that same effect using a datawindow!

Step 1. Create a freeform, external datawindow.
Since the data doesn’t matter, create this as an external dw with a single string column. You won’t have to bother with an InsertRow() or SetItemXXX(), so even the name of the column is immaterial. In the TipsnTrick sample app (which can be downloaded from the Box.net widget on the front page of this blog.) I called this datawindow “d_gradient_only”.

Step 2. Set the gradient properties in the datawindow background
I chose a subtle angled gradient that transitions from Teal in the upper left-hand corner, to Silver in the lower right.  The figure below shows the Background properties panel for that datawindow. Mine are just examples – choose your own color schemes and brush types.

Background properties panel

The Angle property setting only pertains to the AngleGradient brush mode, and it controls the direction of the transition from color #1 to color #2. I have that set at about 20, which causes the transition to go from top-left to bottom-right. Experiment with the various gradient settings to get the exact look that you want.

Step 3: Drop a datawindow control on your window or user object.
This is easy PowerBuilder 101 stuff. You place a datawindow control on the surface of whatever you’re using, and move it to the top left corner. You don’t need to stretch it to fill the entire parent, since we’ll be adding resize logic in step 4. (For you OOP noobs, making these changes to an ancestor class for the window or user_object would be a good design choice here).
In the sample app, I created a user object named uo_gradient_background, and the dw control is named “dw_grad”.

Step 4: Add resize logic so that the datawindow always fills the parent.
Programming note: Window objects come with a “resize” event already defined, but User Objects do not, so if you’re using a custom visual user object, you have to define a prototype for the resize event. If you open the uo_gradient_background object, you’ll see that I have the “resize” event mapped to the pbm_size system event.

Place this code in that event:
setRedraw( FALSE )
dw_grad.resize( newWidth, newHeight )
setRedraw( TRUE )

I also placed one line of code in the window Resize event which resizes the Tab control.
tab_1.resize( newWidth, newHeight )

Now you have a datawindow as the background of the user object (or window, if you went that way), and whenever the parent container is resized, the datawindow always fills the available space. Consider this the actual background of the parent, and drop whatever actual UI controls your users will see right on top of the datawindow. The figure below shows the effect it creates:

gradient

Enjoy! And Happy Holidays!
-Paul-

Posted in PowerBuilder, Software | Tagged , , ,

3rd-party PB Tools (episode 2)

This is the second post in the “Tools that all PB developers should be familiar with” thread. We’re going to stick with PBLPeeper for now, but we’ll be looking at a the PBDEBUG file viewer. This is quite possibly, the coolest feature I’ve ever seen, and one I’m sure you’ll use again and again. Before I begin, let’s review PB application debugging techniques in general.

I’m sure every PowerBuilder developer is familiar with the integrated Debugger. It allows you to step through the code of an application or component, and see exactly what’s happening at runtime. You can inspect and change variable contents to see how your program reacts, you can change the flow of the program and step over or around troublesome code… An integrated step debugger is a critical feature of any programming IDE, and while PowerBuilder’s has taken a beating in public opinion over the years, it’s still the #1 debugging tool we’ve got.

There’s another debugging technique that probably has slipped under the radar for most of you – I’m referring to the /PBDEBUG switch and the resulting .DBG file output. The .DBG file is a line-by-line trace of literally, every line of PowerScript that is executed while running an application.

There are two methods for creating a .DBG file.

1.  When running your application from within the IDE:

PB System Options dialog

In the System Options dialog of the IDE, turn ON the checkbox labelled “Enable PBDebug Tracing”. Specify a path/filename in the “PBDebug output path” field, and check whether you want the .DBG file automatically overwritten or not. As long as these options are set, you’ll get a .DBG file for your application whenever you execute it from within the IDE. It’s important to note that this option slows down execution of your app dramatically, so you do NOT want these on all the time. Typically, I set these options ON, run my app to get the .DBG file, then immediately turn them OFF.

2.  When running your application as a compiled executable

There may be a point where you need your users to create this file for you, and they won’t have the PB IDE installed. Simply create a shortcut for your app’s .EXE file, and add the switch /PBDEBUG to the commandline. This will create the file in the same folder as the .EXE, and it will be named yourApp.dbg.

With either approach, you now have a (probably HUGE) text file containing a line-by-line trace of all the code that got executed during the test. The lines shown below are an excerpt from a typical .DBG file.


Executing event +OPEN for class PFC_W_SPLASH, lib entry PFC_W_SPLASH
  Executing instruction at line 1
  Executing object function +OPEN for class W_POPUP, lib entry W_POPUP
    Executing instruction at line 43
    Executing object function +PFC_PREOPEN for class W_SPLASH, lib entry W_SPLASH
      Executing instruction at line 1
      Executing object function +PFC_PREOPEN for class PFC_W_SPLASH, lib entry PFC_W_SPLASH
      End object function +PFC_PREOPEN for class PFC_W_SPLASH, lib entry PFC_W_SPLASH
      Executing object function OF_SETBASE for class W_SPLASH, lib entry W_SPLASH
        Executing instruction at line 52
        Executing instruction at line 56
        Executing instruction at line 57
        Executing instruction at line 58
        Executing object function +CREATE for class N_CST_WINSRV, lib entry N_CST_WINSRV
          Executing instruction at line 2
          Executing object function TRIGGEREVENT for class N_CST_WINSRV, lib entry N_CST_WINSRV
            Executing system dll function
          End class function TRIGGEREVENT for class N_CST_WINSRV, lib entry N_CST_WINSRV
          Executing instruction at line 3
        End class function +CREATE for class N_CST_WINSRV, lib entry N_CST_WINSRV
        Executing instruction at line 58
        Executing instruction at line 59
        Executing object function OF_SETREQUESTOR for class N_CST_WINSRV, lib entry N_CST_WINSRV
          Executing instruction at line 46
          Executing instruction at line 50
          Executing instruction at line 51
          Executing instruction at line 52
        End class function OF_SETREQUESTOR for class N_CST_WINSRV, lib entry N_CST_WINSRV

The call stack is visualized by indenting each level, so you can see when a method or event is entered and exited. It’s a lot of data to wade through, and basic text editors like Notepad and Wordpad aren’t going to help you mine for any nuggets of truth in there.

PBLPeeper to the rescue!!

PBLPeeper's DEBUG file viewer

In the figure above, I’ve loaded PBLPeeper with the PB 11.5 workspace and target that were used to generate the .DBG file, then went to the Trace tab. This prompts me to load the .DBG file. As the illustration shows, you get a two-paned presentation. The contents of the .DBG file are loaded into the left-hand pane (with handy collapse/expand capabilities). When you click on any line in the .DBG file, the Powerscript for that specific event or function is automatically loaded into the right-hand pane. With this technique, you get to see the actual line of code, in context with its entire script. PBLPeeper handles overridden functions/events as well.

One of the benefits that the /PBDEBUG technique has over the step debugger is handling POSTed events/functions. Since a posted call is simply placed on the Windows message queue, it gets processed the very next time the application yields. If you place a debugger STOP after a call has been posted, but before it has a chance to execute, it will fire “out of place”, and your application will not behave as you intended. The /PBDEBUG approach does not interfere with the Windows event flow, so even posted events/functions can be debugged.

Enjoy!
-Paul-

Posted in PowerBuilder, Software | Tagged , , , ,

Tools that all PowerBuilder developers should be familiar with…

I’m going to make this a regular series, along with the other Tips and Tricks, so if you have any suggestions – please pass them along to me at paul.horan@teamsybase.com.

The first tool out of the box is easily my favorite: PBLPeeper. This is developed and maintained by Terry Voth, a charter member of TeamSybase, and his pet feline Sequel the Techno-KittenSequel the Techno-Kitten

I say “developed and maintained”, but not in a strict formal sense.  Like most of us, Terry has a “day job”, and maintaining PBLPeeper ain’t it…

There’s no schedule of releases or bug patches, and no support hotline. But the good news is, the price is RIGHT.  Terry calls it “charityware” – meaning that if you feel your project saved money by using the tool, please make a donation in Terry’s (and Sequel’s) name to a charity of your choosing.

 

PBLPeeper is, first and foremost, a great PB object browser. It does things that PB itself can’t do, like allow you to navigate up and down the ancestry chain of a class with a single click. You can browse an object without the hassle of a checkout or opening it in its painter. It allows you to see all the goodness that the PB IDE hides from you, like the Forward Declarations, and the overridden/extended script indicator.

Figure 1 shows the main Browse panel from PBLPeeper. 

PBLPeeper Browse panel

I’ve selected a typical PFC-based application target, and I’m browsing the Multitable update service object.  The left hand side of the screen is a Treeview (much like the PB System Tree), and the left side is the code browser panel.  Note the little blue arrow in the bottom right-hand corner, next to the word “Overridden”…  That tells me, in a single glance, whether the event script in the code pane is an override or extension.  Clicking the blue arrow takes me to the corresponding event/function script in the immediate ancestor.  I don’t even need to know which PBL the ancestor is located in!

Here’s another neat trick.  Let’s say I want to look at the code of a PB object in the IDE, but the PBL containing that object isn’t in my library list.  I have to add that PBL to my target’s library list, as well as all the PBLs containing the entire ancestry chain of that object.  In other words, the object has to be  regenerated in the IDE just for me to look at the code of a single method.  PBLPeeper does not have that restriction.  In the PBLs tab, I can add any PBL to my “browser list” and browse any object inside it, regardless of whether or not that object’s ancestors are present.  Obviously, I can’t navigate to the ancestor class if that PBL isn’t loaded, but this is a really handy way to browse, say, older versions of object scripts to visually compare them. 

In coming posts, I’ll cover additional features of PBLPeeper that I use quite extensively, including Object Lists and the PBDEBUG file browser.  In the meantime, I encourage all PB developers to add this tool their arsenal.

-Paul-

Posted in PowerBuilder, Software | Tagged , , , | 1 Comment

Working with PowerBuilder painter layouts

PowerBuilder adopted a new overall painter layout for the IDE with the release of 7.0. (I know that was over a decade ago, and the majority of development shops should have upgraded since then, but you’d be surprised at the number of sites still using PB6.5.) The new “paned” style layouts are a vast departure from the modal property sheet dialogs that existed in 6.5 and earlier releases.

There are some subtle visual cues that were built into the panels, that many not be aware of. The first is the designation of the “active” panel. Many of the available menu selections are based upon the active panel, so it’s a good idea to get familiar with this.

Figure #1 shows the default layout for the Database Painter.

Default database painter layout

Figure 1

There are four separate “panes” in this painter, as the red numbers indicate. Only one is considered the “active” pane. Can you tell which is the active pane in the figure above? I’ll zoom into the upper right-hand corner for a better view:

Figure 2

Figure 2

Compare the small regions above the two X’s in the control menus for the two panes. The one above pane 3 (the Table properties pane) is half-grey and half-blue.  That same region in pane #2 is completely filled in, so it is the active pane, and any context menus that appear will correspond to the whichever pane is active.

Notice that some of the panes are also tabbed themselves.  The tabs cannot be moved when they appear at the top of the pane (as they do in the Table pane).  However, when they appear at the bottom of the pane, you can grab them with the mouse and redock them anywhere within the painter, making them into a separate pane.  You can also grab any pane and redock it back as a tabpage.  Any change to the layout is written into the Registry, and will be reloaded whenever you restart the painter.

As an example, one effective change to make to this default layout is to place the Results pane next to the ISQL pane – side by side. To make this change, just click on the Results tab, and drag it over to the right side of the of the pane. Figure 3 below shows that change.

Figure 3

Figure 3

Now, when you select Execute SQL… in the ISQL pane, the results appear in the Results pane, and they’re immediately visible without having to toggle between hidden panes.

Note the stickpin icons in the upper left hand of each pane. Those behave exactly as you think they would. If they’re clicked into the “stuck” position, the pane titlebar stays visible. If they’re “unstuck”, the pane titlebar will autohide itself, and reappear when the mouse hovers over it.

Once you get a painter looking the way you like it, you can name that layout and save it with an easy-to-remember name.  To save a layout, select View -> Layouts -> Manage.  This dialog window has four buttons across the top. The first one looks like “Save”, but it’s NOT! Think of that button as “Select this layout”.  If you want to save your current pane layout, click the 2nd button – New Layout.  That creates a new entry in the list, which you can give a name. This new layout definition will then appear in the View -> Layouts menu, allowing for quick layout switches.

Should you inadvertently delete the Default layout, or mangle the default to the point that it’s unrecognizable, there’s a quick shortcut for returning PowerBuilder to the factory-installed defaults.

  • Open the Windows Registry.
  • Find the registry key: HKCU\Software\Sybase\PowerBuilder\\Layout\Default.
  • Locate the value for the painter that you’re concerned with, and delete it.
  • When you restart PowerBuilder, that particular painter will be reset to the default layout (and any custom layouts you’ve defined will have been deleted as well.)

    -Paul-

    Posted in PowerBuilder, Software | Tagged , , ,

    Adding custom colors to your PowerBuilder palette

    Have you ever noticed the sixteen “Custom” selections in the dropdownlist for any of the color properties?

    In this list, you can select one of twenty “base” colors (Black, White, Sky, Cream, etc.), or you can select a color that’s linked to the current Windows theme (Button Face, Menu Text, Inactive Title Bar, etc.)   The dynamic selections will automatically change in your app whenever the user changes their Windows appearance in the Control Panel.  Figure 1 shows the selection list and the (mostly) empty custom color choices.

    Color property selections

    Color property selections

    As you can see, most of the custom selections are blank!  How do you assign a custom color to those entries?

    The answer is the menu selection Design > Custom Colors…, as shown in figure 2 below.

    Windows custom color selection dialog

    Windows custom color selection dialog

    There’s a lot going on in this dialog.  You can select one of the predefined colors in the grid, or you can create your own by dragging the “bullseye” pointer inside the color pallette, and then using the contrast slider.  If you know the RGB/HSL values, you can enter them directly in the boxes.

    The process of adding a custom color to the pallette is the following:

    • Click on one of the empty white boxes in the “custom colors” grid;
    • Design the color you want with the sliders or the edit boxes;  
    • Click the “Add to Custom Colors” button.

    The new color is then assigned to the empty box, and it’s supposed to be added to the dropdown list in PowerBuilder.  However, PowerBuilder doesn’t see the new color in the selection list until you exit and restart the IDE.   The color list is kept in the PB.INI file, and we all know that changes to the PB.INI file are not immediately reflected in the IDE.

    Posted in PowerBuilder, Software | Tagged , ,