Design of a class hierarchy for generating a PDF - c++

I am basically having to make a program that will generate a PDF. The PDF will have 3 different page types: a front cover sheet, a general sheet, and a last cover sheet. The header contains a fair amount of information but the header of the front cover sheet and the general sheet only differ by 1 item, however, that one items requires me to shift the others down in coordinates. I have a picture attached to show what I mean.
Also the only purpose the classes are really serving is holding values to represent rectangles that will be used as targets to print text in the pdf. So they really have no need of any functionality aside from the constructor with only initializes the values from a file of constants.
I am trying to use "good" design practice but I am uncertain of what a more efficient method is. It doesn't seem like I can use inheritance that shares the common elements as I will always end up with something I don't need in one of the classes. I thought about just using composition and making a class for each element in the header, that would solve the problem, but then I would have a lot more classes and it would be a class with just to hold one data member which doesn't seem efficient.
So I would just appreciate any suggestions on how to make this a more cohesive and sensible design.
The picture is NOT what I have currently but it is to represent that the data I need seems to be coupled awkwardly or perhaps I am just over complicating this.

Front sheet, general sheets and back sheet have in common that they ARE sheets. A good candidate for your class hierarchy would therefore be:
class sheet { .... };
class front_sheet : public sheet { ...};
class back_sheet : public sheet { ...};
class general_sheet : public sheet { ...};
In sheet, you should put all the common elements, and of course the common behaviour (e.g. print(), save(), get_size(), ...).
There should be a member function that calculates the position of an element in a page. As the rule depends on the kind of page, it would be a virtual function of sheet(), and front and back sheets could overide the default function. This approach will help you to easily manage the different layout of the different pages.
class sheet {
public:
virtual void get_position (int item_no, int& x, int&y) { x=5; y=14*item_no; }
...
};
class back_sheet : public sheet {
public:
void get_position (int item_no, int& x, int&y) { x=5; y = (item==5 ? 14:0); }
...
};
As inheritance really corresponds to a "is-a" relationship, you'll have get a very robust design.
You should however think about the content of your sheet. I see here two main orientations:
you could manage items in a container (e.g. vectors) : it's easier to organise your output in loops instead of copy pasting similar lines of codes for every item
you should ask yourself if the items could have subitems (e.g. a region could contain several subregions, like a print layout with a box and boxes in the box). In this case, i'd recommend the use of the composite pattern
Edit; After having thought about the content, it could be worth coming back again to the sheets, and ask yourself how much different their behaviour really is:
do they have different behaviour thorughout their lifecycle (different way to acquire data for PDF generation or to use dynamically the layout ? In which case the class hierarchy would be ok.
or, after having adopted a dynamic structure such as one suggested above, does it turn out that the only difference is the way you create/construct them ? In this case, it could be worth thinking to keep only one sheet class after all, but having three construction "engines", using either the prototype pattern or the builder pattern. This would however be a significant shift in your application's architecture.

Related

Which component of MV should transform raw data into user friendly format?

There is a structure that holds raw data (consider int) and a gui that should visualize this data. Gui part consists of a few models and and a few standard views (table and tree). The value should be presented either as a string or as a picture depend on user choice. There are some additional difficulties: in some cases the text is different for different elements - i.e., for the same column 0 normally means "Ok", but for a particular element it should be printed as "Yes", also depend on a user choice some columns should not print text for 0 values at all, living a cell empty and don't clutter the table; next, sometimes cell should show two values - e.g., current value and requested - something like "Yes -> No". This also applies to the case when user wants to see icons.
I see two options:
The model forms string text itself and store it somewhere (in the model item may be). The model also forms composite icon from base icons if it is needed. In that scenario I can use standard delegate and just use standard roles reimplementing QAbstractItemModel::data() method.
Reimplement delegates' paint() method (actually I need to reimplement delegates anyway because I need custom editors like QComboBox). The delegate can get any information it needs through the model and custom roles in paint() method and form the string or complex icon itself. As a suboption, I suppose, it's possible for a model to compose needed information itself, like returning std::tuple<int /*value*/, int /*requested value*/, int /*source element type*/, bool /*text or icon*/> in data() method for Qt::DisplayRole.
Update: I want add one thought about second option. Presumably delegates were introduced to handle the work of representing data. One of the consequences of that is the flexibility delegates can give. If you want to see a raw number in some column, you can just leave the default delegate, if you want some additional info presented in a cell you can set a special delegate for that specific column. And it seems you don't need even touch the model or something else.

Eclipse Scout Neon table cell mouseover

I would like to know how to achieve mouseover on a cell, if a column is too short for full text.
So, if I have column with fix width, and text is too long, how to present whole text with mouseover in a cell.
You can dynamically add a mouse over tooltip on any cell by overriding the
execDecorateCell(Cell view, ITableRow row, IColumn<?> col) method in AbstractTable and setting your tooltip text like
#Override
protected void execDecorateCell(Cell view, ITableRow row, IColumn<?> col) {
super.execDecorateCell(view, row, col);
view.setTooltipText("Hi there: " + view.getText());
}
Unfortunately, this does not consider if your text length exceeds the length of your column/cell. It will set the tooltip text in any case! So far, I am not sure, whether (or how) it is possible to calculate (in pixels?), if the actual string length inside a cell exceeds ones column length. Maybe you could try something, that takes the actual string length into account (java.lang.String.length()) and only provide a tooltip if a certain length is given.
Let me know, if this is works for you!
Best regards,
Matthias
The tooltip for truncated text in a table cell is currently only shown if it is not possible to resize the column. This is done by purpose because the tooltip may be very annoying. The code responsible for this is in the file Table.js:
scout.Table.prototype._isTruncatedCellTooltipEnabled = function(column) {
return !this.headerVisible || column.fixedWidth;
};
If you don't like this behaviour, you could adjust the JavaScript code. There are mainly two ways for doing this:
Replace the original function
Extend the table and override the function
With the first approach you replace the actual function, so everytime a scout.Table gets created this function is used. With the second approach you need to make sure your new table is used. In order to do this you need to specify a mapping between the object type and the constructor which will be used whenever an object should be created using scout.create(objectType). This is normally done by convention, so if you write scout.create('Table') a new scout.Table will be created. Because you now want to create a custom table you need to add the mapping to scout.objectFactories.
For me, the first approach feels more like patching, whereas the second one is a cleaner solution. The advantage of the second solution is that the original object stays untouched and you could, at least theoretically, still create regular tables. That's why I suggest to use the second approach. But in the end it is probably a matter of taste.
In both ways, you need to create one or more JavaScript files, register them in yourproject-module.js and include this module in your index.html. The files could look like this:
Approach 1:
patches.js
scout.Table.prototype._isTruncatedCellTooltipEnabled = function(column) {
return true;
};
Approach 2
CustomTable.js
scout.CustomTable = function() {
scout.CustomTable.parent.call(this);
};
scout.inherits(scout.CustomTable, scout.Table);
/**
* #override
*/
scout.CustomTable.prototype._isTruncatedCellTooltipEnabled = function(column) {
return true;
};
objectFactories.js
scout.objectFactories = $.extend(scout.objectFactories, {
'Table': function() {
return new scout.CustomTable();
}
});
Remember: The scout JavaScript code is not api and may change anytime. You won't get compile errors if the function will be renamed as you are used to with java. So before adding a lot of custom JavaScript code to adjust the default behaviour you should consider opening a bug first so that it can be fixed in Scout. It could help others as well.

C++ : Generic interface design for Database

I have a class which is used to create connection with database:
class DBHandler
{
public:
DBHandler();
~DBHandler();
int connect();
int execQuery( string query);
string getField( int row, int col);
};
Now there is another class which is used to fetch some info from database,
class DBManager
{
public:
DBManager();
~DBManager();
//Approach 1
string getUsername()
{
//create a query here and use object of DBHandler class to execute it.
}
//Approach 2
string getUsername (struct QueryDetails& qDetails)
{
//create query using fields of structure and execute the query using DBHandler class.
}
};
Now here is the problem:
1 ) which approach should I follow:
A) If I use approach 1, then I need to hard code query.
B) If I use approach 2, then I need to fill structure each time before calling to function getUsername.
2 ) Is there any better solution except these two which would be generic ?
PS : Definition of structure
struct QueryDetails
{
string tableName;
vector<string> colList;
...
};
Your question is very broad, and the elements you give do not permit to propose you an objective best answer.
Your approach 1 has the following advantages:
it is a robust and secure approach : The queries are written with knowledge of the relevant object
if the database evolve it's easy to find out (text search) where specific queries are made for the tables, and updated the querying code for your object
if your object evolves, needless to say, that you'll immediately realise what you have to change on the database side
The main inconvenience, is that you're tightly linked to the database. If tomorrow you change from PostGres to something else, you have to rewrite every query.
Your approach 2 has the following advantages:
It is very flexible
If your database change, you have to change only the generic functions.
The inconvenience is that this flexibility bears a lot of risks for the maintenance: you can't be sure that the correct query is send by the client, and impact assessment of database layout changes are very difficult to assess.
So finally, it's up to you to decide which one would more fit your needs.
I'd personally tend to favour 1. But this is subjective, and I'd anyway introduce an additional layer to make the application code more independent of the database system that implements access to database.
However, depending on your need, a greater flexibility could be of advantage. For instance, if your class is in fact meant to be a middle layer for other calsses to fetch their own data, then approach 2 could be the best option.

QListWidget performance with many custom items

I have a list with about 2500 custom items. I set them with:
const std::vector<const Items::AbstractItem *> results = _engine.request(text);
if (!results.empty())
{
for (auto i : results){
QListWidgetItem *lwi = new QListWidgetItem;
_results->addItem(lwi);
ListItemWidget *w = new ListItemWidget;
w->setName(i->name());
w->setTooltip(i->path());
_results->setItemWidget(lwi, w);
}
_results->setFixedHeight(std::min(5,_results->count()) * 48); // TODO
_results->show();
}
This takes about 5 seconds on an i5-4590. Hiding the widget is twice as fast. Is this normal or do I have look for errors?
A few ideas:
Try assigning proper parents to your QWidgets, thats way the layout doesn't have to do this
mapping for you. This should help performance.
Call setUpdatesEnable(false) before starting the insert, and to true after it's done
As for hiding the widget while adding large amounts of items, this will help to alleviate extraneous update calls. The second suggestion above should mitigate that.
I think this is fully expected behavior for controls like Lists or Trees that are not based on any data model. And I believe that the data model was invented mainly to fix this issue.
In your situation you have a ListWidget control that stores its data on its own. You need to pass all 2500 items before your app can go on, and you need to do this even if your list shows only 10 items at a time. Even if you just run and close your app, the user won't see all the items but you still need to pass them to your ListWidget. Some GUI frameworks use internal allocation of items and in such case they can optimize things a bit, you could do the same if you allocated your Items in chunks but it's still not a good solution.
Now let's say you introduce some object that could be asked about item properties. The Control will ask about some item and your object will respond with the contents. Your object don't even need to know about all your items, it will just learn when needed.
You Control can ask about few first items and stop when it realize it can fill up its entire height. This way you can avoid work that is not needed for now. The Control can also ask about the item count, so it can set-up its vertical slider.
It needs to be said that the model will not solve your problem automatically, it's just a programming paradigm that allows you to do it better.
So the solution for you would be to replace your QListWidget with a QListView and implement you own data model inheriting QAbstractListModel. You could pass the results to the model and it will pass the items data when needed.
If your QListWidgetItem's always has fixed size, call setUniformItemSizes on your QListWidget, pass true.

Virtual List Controls (MFC)

I am using a List Control to display a representation of elements within a vector. When the list is clicked on another control shows information about that element. The index of the element is currently determined by its index in the control, however if I wish to sort or filter the results this will no longer work.
I have been told that I could use a virtual list control, but the MSDN is not very friendly, can someone run me through how I could use a virtual list control for this?
Frankly - tying data (the position in your data vector) to the presentation of the data in the list control (the position in the list ctrl) is something I would stay away from.
In MFC each control has a "Data" DWORD member variable - when coding in MFC I Always called "SetItemData" for each item added and passed in a pointer that the relevant row referred to e.g.
YourListCtrl.SetItemData((DWORDPTR)&YourData);
Then when the ListCtrl item is selected, you just call
DataTypeYouWant* pData = (DataTypeYouWant*)(YourListCtrl.GetItemData(indexofselecteditem));
Or somesuch thing.
Alternatively - if you don't want to use pointers - hold the index of the item in your original vector in the itemdata for your row (just pass it into the above fns).
To use a virtual list control, set the LVS_OWNERDATA style. You then need to handle the LVN_GETDISPINFO notification message (which is sent via WM_NOTIFY).
If you do this, you are entirely responsible for the data, including the order in which it is shown. Therefore it is up to you to handle sorting and so forth.
By far the easiest way is just to use the item data to set/get an ID that can be used to retrieve the original data, whether that's a vector index or a pointer to the data, or even a key into an associative container.
It really depends on the performance you require.
I have personally seen MAJOR increases in performance for lists holding massive amount of data. However it is much more work to implement, thus for simple uses with not so many data I recommend staying away from it.
Basically, what happens with virtual list controls is that you have your data somewhere in some data structure of your own. Since the list view shows only a small subset of the whole data, it queries you for the content to display when ever something happens (redraw necessary, scroll up or down, change the sorting, etc.).
I don't have handy examples for you. But you can look on codeguru, I am quite sure there are very good examples to start from.
The purpose of virtual list controls is totally different: You should use it for performance reason when you have A LOT of items in your list (I'd say 2500+).
In your case, all you need is to store the vector index in the list item data as NotJarvis explains.