[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Help needed in print-manager using QThread
From:       dantti85-dev () yahoo ! com ! br
Date:       2010-04-18 20:58:40
Message-ID: 828265.9645.qm () web114209 ! mail ! gq1 ! yahoo ! com
[Download RAW message or body]

Hi all,

As I posted into my blog I was working on a replacement
to the python versions of printer-applet and kcm-printer
using C++. The results you can see in
in trunk/playground/base/print-manager/  r1112709.

I'll enumerate the benefits here to avoid discussions:
- it handles cups authentication correctly
- it uses 13mb less of memory to just look for print jobs
- the kcm module can show a different icon for the different
  kinds of printers and in the future I plan to read Mac icons
  to be able to show the manufacturer icon is available.
- to the users I showed they found the UI easier

Before I explain the problem I'm having I'll explain the
dir structure:
- print-manager-kcm, manages printers
- print-queue, show the print queue
- printd, a kded module that shows a systray icon whenever it founds a job
- libqcups, it's a lib shared lib between only print-queue and print-manager-kcm,
  it is like a Qt binding of the cups api making it easier to extend and use, it manages
  the authentication and such..

The issue:
all these parts are basically finished (need some polising still but already works),
so now that I know cups api well enough and things works I decided
to add the "add printer" UI, and I realized that the call would block the UI for
30 seconds, currently if you put a wrong password it also blocks till the 
password dialog is shown again (just like when you do su).
Print-manager definitely needs threads, but it's library uses too many
global variables which make it impossible to create a thread to every
request, actually it is possible but as it creates a thread for each new thread
you would need to type you password EVERY time you needed a
privileged action (and no PolicyKit is not an option).

What I did, created a singleton, which creates a thread that has a local event loop.
this even loop allow us to send the request which give us a queue for free
(so no problem with the global cups variables as long all cups requests
are done in this thread - which is easy to do). Now to don't block
the UI it invokes the thread method and start an event loop to be able to
wait till his request was processed, the request receives the QEventLoop
pointer to call loop->exit() when it finishes.
If the thread needs to authenticate it calls the main thread with
QueuedBlockConnection which makes the other call not be processed
an thus not changing the infamous globals vars.

This is beautiful if it really worked :P Thiago already helped me a lot,
but now I'm with a complicated problem which I can't solve and is
a bit hard to help without testing...

How to test:
$ kcmshell4 kcm_printer_manager
this KCM has a timer which in 1 second updates the UI with new info,
now everything in broken in the latest revision 1116183 so please only
test what I'm saying otherwise you might not see the problem.

only the getDest function and setShared goes to the cups thread function,
so if we call them not at the same time there is no problem (ie disable timer).
but if the timer is enable there are 3 things that can happen:
- it works (yes sometimes it works)
- it does not works and after you put you password the dialog quits but
  it never returns from exec()
- it does not return from getDests nor setShared nor show the password dialog
  the worst case :P

where these things are called:
print-manager-kcm/PrinterModel.cpp # 64
 dests = QCups::getDests(-1, requestAttr);

libqcups/QCups.cpp # 174
QList<QCups::Destination> QCups::getDests(int mask, const QStringList &requestedAttr)

print-manager-kcm/PrintKCM.cpp # 71
m_updateT->start(); // QTimer that updates the model

print-manager-kcm/PrinterDescription.cpp # 71
setIsShared(QCups::Dest::setShared(m_destName, m_isClass, sharedCB->isChecked()));

libqcups/QCups.cpp # 331
bool QCups::Dest::setShared(const QString &destName, bool isClass, bool shared)

the setShared will endup calling through the thread
libqcups/QCups.cpp # 251
void NCups::showPasswordDlg(const QString &username, bool showErrorMessage)

All the functions in QCups.cpp are declared in CupsActions.h

I really really would like to have this included in KDE 4.5 but as the 26 day
is getting near this is a bloker, that's why I really need help with skilled ppl
that have experience with threads an gui...

Thanks,________________________________
Daniel Nicoletti - KDE Developer
http://dantti.wordpress.com
When a wicked man dies, his hope perishes;
all he expected from his power comes to nothing. Prov. 11:7



      

 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic