Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / ui / dialog / icon-preview.cpp
index e74e47ca3797dbc5da70332290855d58803f4285..b507d9f9af4f05911483935289211c44d8764a9b 100644 (file)
@@ -5,6 +5,7 @@
  *   Jon A. Cruz
  *   Bob Jamison
  *   Other dudes from The Inkscape Organization
+ *   Abhishek Sharma
  *
  * Copyright (C) 2004 Bob Jamison
  * Copyright (C) 2005,2010 Jon A. Cruz
@@ -41,6 +42,8 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root,
                   const gchar *name, unsigned int psize );
 }
 
+#define noICON_VERBOSE 1
+
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
@@ -85,7 +88,10 @@ IconPreviewPanel::IconPreviewPanel() :
     desktop(0),
     document(0),
     timer(0),
+    renderTimer(0),
     pending(false),
+    minDelay(0.1),
+    targetId(),
     hot(1),
     selectionButton(0),
     desktopChangeConn(),
@@ -96,6 +102,8 @@ IconPreviewPanel::IconPreviewPanel() :
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     numEntries = 0;
 
+    bool pack = prefs->getBool("/iconpreview/pack", true);
+
     std::vector<Glib::ustring> pref_sizes = prefs->getAllDirs("/iconpreview/sizes/default");
     std::vector<int> rawSizes;
 
@@ -168,10 +176,14 @@ IconPreviewPanel::IconPreviewPanel() :
         Glib::ustring label(*labels[i]);
         buttons[i] = new Gtk::ToggleToolButton(label);
         buttons[i]->set_active( i == hot );
-        Gtk::Frame *frame = new Gtk::Frame();
-        frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
-        frame->add(*images[i]);
-        buttons[i]->set_icon_widget(*Gtk::manage(frame));
+        if ( prefs->getBool("/iconpreview/showFrames", true) ) {
+            Gtk::Frame *frame = new Gtk::Frame();
+            frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+            frame->add(*images[i]);
+            buttons[i]->set_icon_widget(*Gtk::manage(frame));
+        } else {
+            buttons[i]->set_icon_widget(*images[i]);
+        }
 
         tips.set_tip((*buttons[i]), label);
 
@@ -182,7 +194,7 @@ IconPreviewPanel::IconPreviewPanel() :
         align->add(*buttons[i]);
 
         int pad = 12;
-        if ((avail == 0) && (previous == 0)) {
+        if ( !pack || ( (avail == 0) && (previous == 0) ) ) {
             verts->pack_end(*align, Gtk::PACK_SHRINK);
             previous = sizes[i];
             avail = sizes[i];
@@ -216,7 +228,7 @@ IconPreviewPanel::IconPreviewPanel() :
     splitter.pack2( *actuals, false, false );
 
 
-    selectionButton = new Gtk::CheckButton(_("Selection")); // , GTK_RESPONSE_APPLY
+    selectionButton = new Gtk::CheckButton(C_("Icon preview window", "Sele_ction"), true);//selectionButton = (Gtk::ToggleButton*) gtk_check_button_new_with_mnemonic(_("_Selection")); // , GTK_RESPONSE_APPLY
     magBox->pack_start( *selectionButton, Gtk::PACK_SHRINK );
     tips.set_tip((*selectionButton), _("Selection only or whole document"));
     selectionButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::modeToggled) );
@@ -242,6 +254,11 @@ IconPreviewPanel::~IconPreviewPanel()
         delete timer;
         timer = 0;
     }
+    if ( renderTimer ) {
+        renderTimer->stop();
+        delete renderTimer;
+        renderTimer = 0;
+    }
 
     selChangedConn.disconnect();
     docModConn.disconnect();
@@ -255,6 +272,22 @@ IconPreviewPanel::~IconPreviewPanel()
 //#########################################################################
 
 
+#if ICON_VERBOSE
+static Glib::ustring getTimestr()
+{
+    Glib::ustring str;
+    GTimeVal now = {0, 0};
+    g_get_current_time(&now);
+    glong secs = now.tv_sec % 60;
+    glong mins = (now.tv_sec / 60) % 60;
+    gchar *ptr = g_strdup_printf(":%02ld:%02ld.%06ld", mins, secs, now.tv_usec);
+    str = ptr;
+    g_free(ptr);
+    ptr = 0;
+    return str;
+}
+#endif // ICON_VERBOSE
+
 void IconPreviewPanel::setDesktop( SPDesktop* desktop )
 {
     Panel::setDesktop(desktop);
@@ -268,7 +301,7 @@ void IconPreviewPanel::setDesktop( SPDesktop* desktop )
         this->desktop = Panel::getDesktop();
         if ( this->desktop ) {
             docReplacedConn = this->desktop->connectDocumentReplaced(sigc::hide<0>(sigc::mem_fun(this, &IconPreviewPanel::setDocument)));
-            if (this->desktop->selection) {
+            if ( this->desktop->selection && Inkscape::Preferences::get()->getBool("/iconpreview/autoRefresh", true) ) {
                 selChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(this, &IconPreviewPanel::queueRefresh)));
             }
         }
@@ -284,7 +317,9 @@ void IconPreviewPanel::setDocument( SPDocument *document )
 
         this->document = document;
         if (this->document) {
-            docModConn = this->document->connectModified(sigc::hide(sigc::mem_fun(this, &IconPreviewPanel::queueRefresh)));
+            if ( Inkscape::Preferences::get()->getBool("/iconpreview/autoRefresh", true) ) {
+                docModConn = this->document->connectModified(sigc::hide(sigc::mem_fun(this, &IconPreviewPanel::queueRefresh)));
+            }
             queueRefresh();
         }
     }
@@ -296,38 +331,50 @@ void IconPreviewPanel::refreshPreview()
     if (!timer) {
         timer = new Glib::Timer();
     }
-    if (timer->elapsed() < 0.1) {
+    if (timer->elapsed() < minDelay) {
+#if ICON_VERBOSE
+        g_message( "%s Deferring refresh as too soon. calling queueRefresh()", getTimestr().c_str() );
+#endif //ICON_VERBOSE
         // Do not refresh too quickly
         queueRefresh();
     } else if ( desktop ) {
+#if ICON_VERBOSE
+        g_message( "%s Refreshing preview.", getTimestr().c_str() );
+#endif // ICON_VERBOSE
+        bool hold = Inkscape::Preferences::get()->getBool("/iconpreview/selectionHold", true);
+        SPObject *target = 0;
         if ( selectionButton && selectionButton->get_active() )
         {
-            Inkscape::Selection * sel = sp_desktop_selection(desktop);
-            if ( sel ) {
-                //g_message("found a selection to play with");
-
-                GSList const *items = sel->itemList();
-                SPObject *target = 0;
-                while ( items && !target ) {
-                    SPItem* item = SP_ITEM( items->data );
-                    SPObject * obj = SP_OBJECT(item);
-                    gchar const *id = obj->getId();
-                    if ( id ) {
-                        target = obj;
+            target = (hold && !targetId.empty()) ? desktop->doc()->getObjectById( targetId.c_str() ) : 0;
+            if ( !target ) {
+                targetId.clear();
+                Inkscape::Selection * sel = sp_desktop_selection(desktop);
+                if ( sel ) {
+                    //g_message("found a selection to play with");
+
+                    GSList const *items = sel->itemList();
+                    while ( items && !target ) {
+                        SPItem* item = SP_ITEM( items->data );
+                        SPObject * obj = SP_OBJECT(item);
+                        gchar const *id = obj->getId();
+                        if ( id ) {
+                            targetId = id;
+                            target = obj;
+                        }
+
+                        items = g_slist_next(items);
                     }
-
-                    items = g_slist_next(items);
-                }
-                if ( target ) {
-                    renderPreview(target);
                 }
             }
         } else {
-            SPObject *target = desktop->currentRoot();
-            if ( target ) {
-                renderPreview(target);
-            }
+            target = desktop->currentRoot();
         }
+        if ( target ) {
+            renderPreview(target);
+        }
+#if ICON_VERBOSE
+        g_message( "%s  resetting timer", getTimestr().c_str() );
+#endif // ICON_VERBOSE
         timer->reset();
     }
 }
@@ -338,9 +385,15 @@ bool IconPreviewPanel::refreshCB()
     if (!timer) {
         timer = new Glib::Timer();
     }
-    if ( timer->elapsed() > 0.1 ) {
+    if ( timer->elapsed() > minDelay ) {
+#if ICON_VERBOSE
+        g_message( "%s refreshCB() timer has progressed", getTimestr().c_str() );
+#endif // ICON_VERBOSE
         callAgain = false;
         refreshPreview();
+#if ICON_VERBOSE
+        g_message( "%s refreshCB() setting pending false", getTimestr().c_str() );
+#endif // ICON_VERBOSE
         pending = false;
     }
     return callAgain;
@@ -350,6 +403,9 @@ void IconPreviewPanel::queueRefresh()
 {
     if (!pending) {
         pending = true;
+#if ICON_VERBOSE
+        g_message( "%s queueRefresh() Setting pending true", getTimestr().c_str() );
+#endif // ICON_VERBOSE
         if (!timer) {
             timer = new Glib::Timer();
         }
@@ -360,7 +416,11 @@ void IconPreviewPanel::queueRefresh()
 void IconPreviewPanel::modeToggled()
 {
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-    prefs->setBool("/iconpreview/selectionOnly", (selectionButton && selectionButton->get_active()));
+    bool selectionOnly = (selectionButton && selectionButton->get_active());
+    prefs->setBool("/iconpreview/selectionOnly", selectionOnly);
+    if ( !selectionOnly ) {
+        targetId.clear();
+    }
 
     refreshPreview();
 }
@@ -369,8 +429,14 @@ void IconPreviewPanel::renderPreview( SPObject* obj )
 {
     SPDocument * doc = SP_OBJECT_DOCUMENT(obj);
     gchar const * id = obj->getId();
+    if ( !renderTimer ) {
+        renderTimer = new Glib::Timer();
+    }
+    renderTimer->reset();
 
-//    g_message(" setting up to render '%s' as the icon", id );
+#if ICON_VERBOSE
+    g_message("%s setting up to render '%s' as the icon", getTimestr().c_str(), id );
+#endif // ICON_VERBOSE
 
     NRArenaItem *root = NULL;
 
@@ -380,7 +446,7 @@ void IconPreviewPanel::renderPreview( SPObject* obj )
     /* Create ArenaItem and set transform */
     unsigned int visionkey = SPItem::display_key_new(1);
 
-    root = SP_ITEM( SP_DOCUMENT_ROOT(doc) )->invoke_show ( arena, visionkey, SP_ITEM_SHOW_DISPLAY );
+    root = SP_ITEM( doc->getRoot() )->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY );
 
     for ( int i = 0; i < numEntries; i++ ) {
         guchar * px = sp_icon_doc_icon( doc, root, id, sizes[i] );
@@ -396,8 +462,13 @@ void IconPreviewPanel::renderPreview( SPObject* obj )
     }
     updateMagnify();
 
-    SP_ITEM(sp_document_root(doc))->invoke_hide(visionkey);
+    SP_ITEM(doc->getRoot())->invoke_hide(visionkey);
     nr_object_unref((NRObject *) arena);
+    renderTimer->stop();
+    minDelay = std::max( 0.1, renderTimer->elapsed() * 3.0 );
+#if ICON_VERBOSE
+    g_message("  render took %f seconds.", renderTimer->elapsed());
+#endif // ICON_VERBOSE
 }
 
 void IconPreviewPanel::updateMagnify()
@@ -422,4 +493,4 @@ void IconPreviewPanel::updateMagnify()
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :