Bug 58809 - Image export via command line
Summary: Image export via command line
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR wishlist
Target Milestone: ---
Assignee: Umbrello Development Group
URL:
Keywords:
: 75464 125964 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-05-22 18:00 UTC by Jonathan Riddell
Modified: 2006-04-20 22:05 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
patch + new files (3.62 KB, patch)
2005-08-05 09:59 UTC, Alan Ezust
Details
a patch which is supposed to add "export all" to the menu, but doesn't quite work yet (7.18 KB, text/plain)
2005-08-08 01:58 UTC, Alan Ezust
Details
exportAll now saves to same dir as doc (13.50 KB, text/plain)
2005-08-08 07:54 UTC, Alan Ezust
Details
"Export all views" can keep view folders when exporting (79.74 KB, patch)
2006-03-31 04:56 UTC, Daniel Calviño Sánchez
Details
Fixed command line crashes (14.11 KB, patch)
2006-04-05 04:37 UTC, Daniel Calviño Sánchez
Details
Fixes overwrite confirmation dialog when exporting an image (689 bytes, patch)
2006-04-15 02:12 UTC, Daniel Calviño Sánchez
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Riddell 2003-05-22 18:00:50 UTC
Version:            (using KDE Devel)
Installed from:    Compiled sources

In order to include up to date UML diagrams in automatically generated documentations, it  
would be nice to have a tool without GUI, which renders PNG images from a given Umbrello   
xml project file.
Comment 1 Jonathan Riddell 2003-05-22 18:01:48 UTC
that wishlist from Dirk Tiedtke <d.tiedtke@powitec.de>
Comment 2 Jonathan Riddell 2003-05-22 18:02:26 UTC
This is possible with dcop, although the GUI would need to be loaded up first.
Comment 3 Jonathan Riddell 2004-02-20 14:30:05 UTC
*** Bug 75464 has been marked as a duplicate of this bug. ***
Comment 4 Mathieu Jobin 2004-08-25 00:08:18 UTC
could dcop be modified to start application that is not running and shut them off when done ?

Comment 5 Bernhard Sonderegger 2004-08-31 11:43:55 UTC
exporting SVG format would be nice too
Comment 6 Vasek Smidl 2005-03-10 22:34:38 UTC
I would also loved to see this functionality and I do not mind that GUI is loaded. Export of all diagrams is a must for documenting larger projects.

DCOP is certainly a good tool for that but I did not managed to do it. Can anyone give a hint how to export one diagram via DCOP? 
I hope I will be able to code the rest, and post it here. Thanks.
Comment 7 Alan Ezust 2005-08-05 07:09:07 UTC
I am currently working on this bug. It's the first time I've delved into KDE, so I have a a couple of questions, which I hope someone can help me with. I should have this done in a couple of days.

1. Is it feasible to try to export the UmlView objects before the call to the kapplication->exec()? 

  I notice that the images are not fully rendered just yet - I'm assuming it's necessary to call exec() first, wait a few cycles, and then do the export.

Which means i'll probably want to add a new KAction, "export all views" (since each .xmi file can have more than a single UmlView). Fortunately, each view remembers its filename.

2. I'm familiar with qmake .pro files where you add things to HEADERS and SOURCES.

   I found Makefile.am, which contains SOURCES, but where do I add the HEADERS? In particular, if I am adding a new QObject derived class with signals/slots, how do I tell the make system to do its moc thing on it in KDE?

3.   After I change Makefile.am, what is the correct step to properly rebuild the project?

Comment 8 Alan Ezust 2005-08-05 07:20:40 UTC
found answers to the make issues in the FAQ 
http://developer.kde.org/documentation/other/developer-faq.html#q2.4

so feel free to disregard the questions.
Comment 9 Alan Ezust 2005-08-05 09:46:23 UTC
I have successfully patched umbrello 1.4 with this enhancement. 
 
It requires that all of the UMLViews have a proper name already (otherwise it does not save them). 

It works this way

umbrello [-e png] [filename.xmi]
umbrello [-e eps] [filename.xmi]

exports all views to the specified format.

I was having difficulty figuring out how to svn co the 3.5 trunk - I noticed that the svn is now qt4, which does not build yet. How should I send you the diffs? Does it make sense to svn co the stable version?

Comment 10 Alan Ezust 2005-08-05 09:59:58 UTC
Created attachment 12087 [details]
patch + new files
Comment 11 Oliver Kellogg 2005-08-05 12:15:21 UTC
SVN commit 443195 by okellogg:

Patch from Alan Ezust adds image export via command line.
I have not yet tested this stuff; can we close the PR?
CCBUG:58809


 M  +2 -1      ChangeLog  
 M  +2 -0      THANKS  
 M  +1 -0      umbrello/Makefile.am  
 M  +15 -2     umbrello/main.cpp  
 M  +48 -0     umbrello/umlview.cpp  
 M  +11 -0     umbrello/umlview.h  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #443194:443195
@@ -5,10 +5,11 @@
 * Code generator for Tcl
 * Externalization of folders (i.e. submodel files)
 * Change interface into class and vice versa (if abstract and no attributes)
+* Image export via command line
 * Automatic Diagram Layout (67059, not yet closed)
 
 * Bugs fixed / wishes implemented (see http://bugs.kde.org)
-57588 67719 72016 79433 87252 88117 97162 105564 108223 109591 109636
+57588 58809 67719 72016 79433 87252 88117 97162 105564 108223 109591 109636
 
 Version 1.4.2 (maintenance release)
 
--- branches/KDE/3.5/kdesdk/umbrello/THANKS #443194:443195
@@ -25,6 +25,7 @@
 Albert Astals Cid <tsdgeos @terra.es>
 Richard Dale <duke @tipitina.demon.co.uk>
 Vincent Decorges <vincent.decorges @eivd.ch>
+Alan Ezust <alan.ezust @gmail.com>
 Jean-Remy Falleri <jr.falleri @gmail.com>
 Andi Fischer <andi.fischer @hispeed.ch>
 Pascal Fleury <fleury @users.sourceforge.net>
@@ -47,6 +48,7 @@
 Laurent Montel <montel @kde.org>
 Lutz Mueller <lutz.mueller @gmx.de>
 Heiko Nardmann <heiko.nardmann @onlinehome.de>
+Dimitri Ognibene <ognibened @yahoo.it>
 Carsten Pfeiffer <pfeiffer @kde.org>
 Ivan Porres <iporres @abo.fi>
 Ruediger Ranft <kdebugs @rranft1.mail.htwm.de>
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/Makefile.am #443194:443195
@@ -43,6 +43,7 @@
 enum.cpp \
 enumliteral.cpp \
 enumwidget.cpp \
+exportviewaction.cpp \
 floatingtext.cpp \
 kplayerslideraction.cpp \
 hierarchicalcodeblock.cpp \
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/main.cpp #443194:443195
@@ -14,7 +14,8 @@
 
 #include "uml.h"
 #include "version.h"
-
+#include "umlview.h"
+#include "exportviewaction.h"
 #include "kstartuplogo.h"
 
 #include <kaboutdata.h>
@@ -36,6 +37,7 @@
 static KCmdLineOptions options[] =
     {
         { "+[File]", I18N_NOOP("File to open"), 0 },
+        { "export <extension>", I18N_NOOP("export diagrams to extension and exit"), 0},
         // INSERT YOUR COMMANDLINE OPTIONS HERE
         KCmdLineLastOption
     };
@@ -82,7 +84,7 @@
         KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
         if ( args -> count() ) {
             uml -> openDocumentFile( args -> url( 0 ) );
-            args -> clear();
+            // args -> clear();  // Why is this necessary?
         } else {
             cfg -> setGroup( "General Options" );
             bool last = cfg -> readBoolEntry( "loadlast", false );
@@ -93,6 +95,17 @@
                 uml->newDocument();
             }
         }
+        QCStringList exportOpt = args->getOptionList("export");
+        if (exportOpt.size() > 0) {
+        for (QCStringList::iterator itr = exportOpt.begin();
+            itr != exportOpt.end(); ++itr) {
+                QString extension = QString(*itr);
+                kdDebug() << "extension: " << extension << endl;
+                ExportViewAction eva(extension);
+                eva.exportAllViews();
+            }
+            return 0;
+        }
         if ( showLogo && !start_logo->isHidden() ) {
             start_logo->raise();
         }
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlview.cpp #443194:443195
@@ -1444,6 +1444,54 @@
 
 }
 
+void UMLView::exportImageTo(QString imageMimetype) {
+    KTempFile tmpfile;
+    QString extDef = mimeTypeToImageType(imageMimetype).lower();
+    QString file = getName() + "." + extDef;
+    kdDebug() << "m_ImageURL: " << m_ImageURL.fileName() << endl;
+    if (!m_ImageURL.isEmpty()) {
+      file = tmpfile.name();
+    }
+    
+    QFileInfo info(file);
+    QString ext = info.extension(false);
+
+    QRect rect = getDiagramRect();
+    if (rect.isEmpty()) {
+        kdDebug() << "Can not save an empty diagram" << endl;
+        return;
+    }
+    kdDebug() << "ExportImageTo: " << file << endl;
+    if (imageMimetype == "image/x-eps") {
+        printToFile(file,true);
+    } else if (imageMimetype == "image/svg+xml") {
+        QPicture* diagram = new QPicture();
+        QPainter* painter = new QPainter();
+        painter->begin( diagram );
+
+        /* make sure the widget sizes will be according to the
+         actually used printer font, important for getDiagramRect()
+         and the actual painting */
+        forceUpdateWidgetFontMetrics(painter);
+
+        QRect rect = getDiagramRect();
+        painter->translate(-rect.x(),-rect.y());
+        getDiagram(rect,*painter);
+        painter->end();
+        diagram->save(file, mimeTypeToImageType(imageMimetype).ascii());
+
+        // delete painter and printer before we try to open and fix the file
+        delete painter;
+        delete diagram;
+        // next painting will most probably be to a different device (i.e. the screen)
+         forceUpdateWidgetFontMetrics(0);
+    } else {
+        QPixmap diagram(rect.width(), rect.height());
+        getDiagram(rect, diagram);
+        diagram.save(file, mimeTypeToImageType(imageMimetype).ascii());
+    }
+}
+
 void UMLView::exportImage() {
     UMLApp *app = UMLApp::app();
     QStringList fmt = QImage::outputFormatList();
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlview.h #443194:443195
@@ -669,6 +669,17 @@
     void copyAsImage(QPixmap*& pix);
 
     /**
+     * Does not pop up any dialogs, but tries to save this
+     * image to the last-saved name. can be called from
+     * command line.
+     * @param mimetype - an alternate mimetype to save as
+     * @todo test further, and later refactor the redundant
+     *     code from exportImage() -- SAE left
+     *     exportImage alone for this exercise
+     */
+    void exportImageTo(QString mimetype);
+
+    /**
      * Saves a png file to the given url.
      */
     void exportImage();
Comment 12 Jonathan Riddell 2005-08-05 13:28:31 UTC
Works for me, thanks for your help.
Comment 13 Alan Ezust 2005-08-08 01:58:54 UTC
Created attachment 12138 [details]
a patch which is supposed to add "export all" to the menu, but doesn't quite work yet

I'm trying to add this as a choice in the UI. I created a new KAction
with a name view_export_all and added an element in the umbrelloui.rc,
but it doesn't show up in the menu.
Is there something else I am missing?
Comment 14 Alan Ezust 2005-08-08 07:54:01 UTC
Created attachment 12141 [details]
exportAll now saves to same dir as doc

This version gets the absolute path of the currently opened document
and exports its images to the same location.
Comment 15 Alan Ezust 2005-08-08 07:57:39 UTC
Comment on attachment 12138 [details]
a patch which is supposed to add "export all" to the menu, but doesn't quite work yet

This patch is obsolete (newer one is better) but my question remains, and the
newer one has the same problem.
Comment 16 Daniel Calviño Sánchez 2006-03-31 04:56:08 UTC
Created attachment 15388 [details]
"Export all views" can keep view folders when exporting

Export all views can preserve view folders when exporting

First of all, the patch right now DOESN'T work because a bug. I've uploaded it
even when it doesn't work hoping that someone can spot the problem.

In the export all option now two more options can be set: the directory where
the images will be exported, and keep the tree structure used to store the
views in the document in the target directory, so if you have your diagrams in
folders created by you in the document, those folders are created when
exporting (Logical view, use case view and so on aren't created). The target
directory can be local or remote, thanks to KIO infrastructure. I think these
options don't overlap with http://bugs.kde.org/87252

I've also refactored a bit the code. All the exporting bulk code was extracted
to "UMLViewImageExporterModel" class. It can export an specific view, or all
the views in the current document. The methods in this class aren't interactive
(apart from asking passwords done by KIO classes). And they don't throw
exceptions, as requested ;) (however, "God kills a kitten everytime a return
value is used as an exception. Please, think of the kittens" :P Only a joke,
don't begin a flame with exceptions :) )

So, to get the parameters for the export (name of the images and extension, for
example), the classes "UMLViewImageExporter" and "UMLViewImageExporterAll" must
be used. The first, to export an specific view. The second, to export all the
views in the document.
A new dialog was added to get the "export all" parameters from the user. The
base interface is in exportallviewsdialogbase.ui, and its extended with the
class ExportAllViewsDialog, which adds a KFileFilterCombo to the dialog (it
wasn't added in the .ui file because QT Designer doesn't support it).

The "export all" can also be made from command line, but this way the export
isn't interactive.

I removed the ExportViewAction because after extracting and merging its code
with UMLView, the main method in the Action was only one line, and I thought it
would be better putting it as a slot in UMLApp.


I changed 'mimetype' strings to 'mimeType' in all the images related code,
because I think it's more consistent with the naming used. I added the GPL
license headers in new files, and updated the years in modified files. The
copyright and authors were also moved into the license section, as Oliver
Kellogg did in uml.cpp in the last commit.


BUG: when the "export all" is used from command line:
-if no directories need to be created, it works (for example, the target
directory exists and there are no views in folders, or the use-folders option
isn't used).
-if a direct child directory of another directory needs to be created, it's
created but the views can't be exported because they're empty.
-if a directory not direct child of an existing one needs to be created, the
directory is created and then the app crashes.

When exporting from GUI it works without problems. I don't know why this
happens, maybe an initialization problem, but I have no idea :( If instead of
using KIO::NetAccess, the QT classes such as QDir are used (as it was before,
if you look the previous code of UMLView), the problem doesn't happen (although
only with local files, remote ones still depend in KIO::NetAccess).


Answering to Alan Ezust, empirically I have found that if you make a change in
the .ui file, you must:
1-Install the application (well, at least, the .ui file) and not only build it.

2-If you've installed it, you must remove any old .ui file which can be lurking
somewhere. For example, if you install the app to /usr/local and you have a
previously installed version in /usr, KDE may get the old .ui file (the one at
/usr/share/apps/umbrello) instead of the newer one.
Comment 17 Oliver Kellogg 2006-04-02 12:19:24 UTC
Thanks for your contribution Daniel.
Here are my findings about the crash.

1) Changed the loop in UMLViewImageExporterModel::getDiagramFileName()
 as follows:

    while (! UMLListView::typeIsRootView(listViewItem->getType())) {
        name.insert(0, listViewItem->getText() + "/");
        listViewItem = static_cast<UMLListViewItem*>(listViewItem->parent());
        if (listViewItem == NULL)
            break;
    }


2) Invocation example:
 umbrello -export png -directory /home/kellogg/tmp -use-folders \
   file:///home/kellogg/xmi/seq-110843.xmi

I had to use the "file://" prefix else umlviewimageexportermodel.cpp:150

    if (!url.isLocalFile()) {
        if (!KIO::NetAccess::upload(tmpFile.name(), url ....

the isLocalFile() would return false and the KIO::NetAccess::upload()
would crash. I.e. the non-local case is still not working.
Comment 18 Oliver Kellogg 2006-04-02 12:29:38 UTC
SVN commit 525494 by okellogg:

Apply attachment 15388 [details] by Daniel Calviño Sánchez with minor changes.
CCBUG:58809


 M  +1 -0      ChangeLog  
 M  +3 -1      umbrello/Makefile.am  
 M  +2 -0      umbrello/dialogs/Makefile.am  
 A             umbrello/dialogs/exportallviewsdialog.cpp   [License: no copyright GPL (v2+)]
 A             umbrello/dialogs/exportallviewsdialog.h   [License: no copyright GPL (v2+)]
 A             umbrello/dialogs/exportallviewsdialogbase.ui  
 D             umbrello/exportviewaction.cpp  
 D             umbrello/exportviewaction.h  
 M  +42 -14    umbrello/main.cpp  
 M  +1 -1      umbrello/umbrelloui.rc  
 M  +18 -7     umbrello/uml.cpp  
 M  +21 -15    umbrello/uml.h  
 M  +18 -1     umbrello/umllistview.cpp  
 M  +6 -0      umbrello/umllistview.h  
 M  +9 -246    umbrello/umlview.cpp  
 M  +9 -24     umbrello/umlview.h  
 A             umbrello/umlviewimageexporter.cpp   [License: no copyright GPL (v2+)]
 A             umbrello/umlviewimageexporter.h   [License: no copyright GPL (v2+)]
 A             umbrello/umlviewimageexporterall.cpp   [License: no copyright GPL (v2+)]
 A             umbrello/umlviewimageexporterall.h   [License: no copyright GPL (v2+)]
 A             umbrello/umlviewimageexportermodel.cpp   [License: no copyright GPL (v2+)]
 A             umbrello/umlviewimageexportermodel.h   [License: no copyright GPL (v2+)]
Comment 19 Daniel Calviño Sánchez 2006-04-05 04:37:42 UTC
Created attachment 15463 [details]
Fixed command line crashes

At least I managed to get it work. I thought that the problem could be that
KIO::NetAccess expected the QT main loop to be running, but as the "app.exec()"
wasn't called when exporting, it caused the strange behaviour (it could be a
stupid hypothesis... but as I don't know anything about the internal code of QT
nor KIO classes it seemed fine to me :P ).

So, using events, I made that the exportAllViews code execution was scheduled
to be processed until the QT loop was running. Once the export is made, a close
event is sent so the application finishes. I don't know if it's the optimal way
to do it, but it works! ;)

As I was modifying the main.cpp file I have also applied some "extract method"
refactoring pattern, and also made that the GUI is kept hidden when the
application is executed using the export all views option.
Comment 20 Oliver Kellogg 2006-04-06 00:07:44 UTC
SVN commit 526907 by okellogg:

Attachment 15463 [details] from Daniel Calviño Sánchez fixes the command line crashes.
Many thanks Daniel for your fine work.
CCBUG:58809


 M  +1 -0      Makefile.am  
 A             cmdlineexportallviewsevent.cpp   [License: GPL (v2+)]
 A             cmdlineexportallviewsevent.h   [License: GPL (v2+)]
 M  +107 -50   main.cpp  
 M  +8 -2      uml.cpp  
 M  +8 -0      uml.h  
Comment 21 Daniel Calviño Sánchez 2006-04-15 02:12:50 UTC
Created attachment 15635 [details]
Fixes overwrite confirmation dialog when exporting an image

Ooops... I used KMessageBox::Ok instead of KMessageBox::Continue when checking
the option selected by the user in the overwrite confirmation dialog. So it
never let you to overwrite the image. The patch fixes the problem.
Comment 22 Oliver Kellogg 2006-04-16 23:47:44 UTC
SVN commit 530496 by okellogg:

Attachment 15635 [details] from Daniel Calviño Sánchez fixes the behavior of the
overwrite confirmation dialog.
CCBUG:58809


 M  +1 -1      umlviewimageexporter.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlviewimageexporter.cpp #530495:530496
@@ -65,7 +65,7 @@
             int wantSave = KMessageBox::warningContinueCancel(0,
                                 i18n("The selected file %1 exists.\nDo you want to overwrite it?").arg(m_imageURL.prettyURL()),
                                 i18n("File Already Exists"), i18n("&Overwrite"));
-            if (wantSave == KMessageBox::Ok) {
+            if (wantSave == KMessageBox::Continue) {
                 exportPrepared = true;
             }
         } else {
Comment 23 Alan Ezust 2006-04-17 00:10:49 UTC
Wow, it doesn't go into graphics mode anymore! Very nice!

Thanks Daniel!
Comment 24 Oliver Kellogg 2006-04-20 22:05:48 UTC
*** Bug 125964 has been marked as a duplicate of this bug. ***